I don't understand why the .NET mutex does not either throw an AbandonedMutexException
in one of the waiting threads or release the mutex when Mutex.Dispose()
is called.
In particular, code like this will deadlock:
public static void testCall()
{
using (var mutex = new System.Threading.Mutex(false, "testname"))
{
mutex.WaitOne();
Console.WriteLine("second call");
}
}
public static void Main(string[] args)
{
var thread = new System.Threading.Thread(testCall);
using (var mutex = new System.Threading.Mutex(false, "testname"))
{
mutex.WaitOne();
Console.WriteLine("first call");
thread.Start();
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 5));
Console.WriteLine("sleep done");
}
thread.Join();
}
Mind you, I understand the AbandonedMutexException
usually comes from the underlying WIN32 mutex and in native code would only be triggered in case the owning thread dies - I've been writing C/C++ code for a long time and am fully aware of the underlying design. I also know that the following code is an easy workaround:
using (var mutex = new System.Threading.Mutex(false, "testname"))
{
mutex.WaitOne();
try
{
Console.WriteLine("first call");
thread.Start();
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 1));
Console.WriteLine("sleep done");
}
finally
{
mutex.ReleaseMutex();
}
}
What I don't understand is the rationale behind .NET mutexes not forcing a release when the object has been explicitly disposed of while holding the lock. Wouldn't that be more in-line with the rest of the .NET programming paradigm? If/when the developer explicitly destroys a locked mutex... it only makes sense to mark it as abandoned.