AbandonedMutexException
.NETミューテックスが待機中のスレッドの1つにスローしないか、Mutex.Dispose()
呼び出されたときにミューテックスを解放しない理由がわかりません。
特に、このようなコードはデッドロックします。
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();
}
念のために言っておきますが、AbandonedMutexException
通常は基盤となるWIN32ミューテックスに由来し、ネイティブコードでは、所有するスレッドが停止した場合にのみトリガーされます。私は長い間C / C ++コードを記述しており、基盤となる設計を十分に認識しています。また、次のコードが簡単な回避策であることも知っています。
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();
}
}
私が理解していないのは、ロックを保持している間にオブジェクトが明示的に破棄されたときに、.NETミューテックスがリリースを強制しない理由です。それは、他の.NETプログラミングパラダイムとより一致しているのではないでしょうか。開発者がロックされたミューテックスを明示的に破棄した場合...それを放棄としてマークすることだけが意味があります。