1

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プログラミングパラダイムとより一致しているのではないでしょうか。開発者がロックされたミューテックスを明示的に破棄した場合...それを放棄としてマークすることだけが意味があります。

4

1 に答える 1

2

あなたはおそらくそれがあなたが提案するように機能することを望まないでしょう。あなたがこれを持っているとしましょう:

using (var m = new Mutex(....))
{
    m.WaitOne();
    // do some stuff here
    // that ends up throwing an exception
}

スレッドがミューテックスを保持している間、例外がスローされます。ミューテックスが破棄の一部として解放された場合、他のスレッドがミューテックスを取得し、更新中のデータでパーティを開始する可能性があります。現在、データが不明な(おそらく一貫性がないか破損している)状態になっていることを除いて。

もちろん、例外を処理してクリーンアップするのが最善ですが、ミューテックスを取得しようとする次のスレッドが何か悪いことが起こったことを認識できるように、ミューテックスを保持したままにする(またはスレッドが停止した場合は放棄する)ことをお勧めします。 。

上記に加えて、自動リリースを追加するには、.NETラッパーがどのスレッドがミューテックスを所有しているかを追跡する必要があります。また、Disposeメソッドはその値をチェックして、を呼び出す必要があるかどうかを判断する必要がありますReleaseMutex。そして、それを追跡することは不可能です。.NETプログラムは、ミューテックスハンドルをアンマネージコードに渡す可能性があり、ラッパーの知らないうちにミューテックスを取得または解放する可能性があります。

したがって、答えは2つあります。1つは、不可能です。第二に、それが可能であったとしても、おそらくその振る舞いは望まないでしょう。

于 2012-04-13T18:38:01.350 に答える