I would start by sending trace output every time a thread is about to enter / exit a critical section, as well as every time it successfully gets a lock. Use the System.Diagnostics.Trace class.
You can then determine from your output the trace in which there is actually a lock.
Typical trace code:
Trace.WriteLine("Acquiring lock - foo"); lock (foo) { Trace.WriteLine("Acquired lock - foo"); // Do some stuff Trace.WriteLine("Releasing lock - foo"); } Trace.WriteLine("Released lock - foo");
Depending on how your program is structured, this may not be useful unless you include thread information in the trace output, for example:
Trace.WriteLine(string.Format("Thread {0} - Acquiring lock - foo", Thread.CurrentThread.ManagedThreadId));
Once you figure out which thread has a lock, you can enter the debugger and see which lock it is waiting for, and then use the same trace output to find out who has another lock. In most cases, two threads are involved in a dead end, and this will allow you to find both of them.
source share