13

初めてミューテックスを使用しようとしていますが、プログラムの2つの別々のインスタンスで次のコードを実行しています

public void asynchronousCode()
    {
        using (var mutex = new Mutex(false, "mySpecialMutex"))
        {
            if (!mutex.WaitOne(1000, false))
            {
                Console.WriteLine("First check - some one locked the mutex");
            }

            if (!mutex.WaitOne(3000, false))
            {
                Console.WriteLine("Second check- some one locked the mutex");
            }
            else
            {
                Console.WriteLine("I got the mutex");
                Console.WriteLine("sleeping");
                Thread.Sleep(3000);
                Console.WriteLine("Awaking and Releasing mutex");
                mutex.ReleaseMutex();
            }
        }
    }

これを実行すると、インスタンスの1つ(最初に実行したもの)が出力されます

I got the mutex
sleeping
awaking and releasing mutex

他のインスタンスは印刷します

First check - some one locked the mutex

そして、最初のインスタンスがミューテックスをリースするとすぐに、例外を除いて2番目の待機ステートメントでクラッシュします。

The wait completed due to an abandoned mutex.

なぜこの例外が発生するのか、どうすればそれを防ぐことができるのかについてのアイデアはありますか?

解決策:おそらくmdsnのドキュメントをもっと明確に読むべきでした。私を正しい方向に向けてくれてありがとうアンドリュー

WaitHandle.WaitOneメソッドを使用して、ミューテックスの所有権を要求できます。ミューテックスを所有するスレッドは、その実行をブロックすることなく、WaitOneへの繰り返しの呼び出しで同じミューテックスを要求できます。ただし、ミューテックスの所有権を解放するには、スレッドはReleaseMutexメソッドを同じ回数呼び出す必要があります。ミューテックスクラスはスレッドIDを強制するため、ミューテックスはそれを取得したスレッドによってのみ解放できます。

4

2 に答える 2

19

問題は、Mutexを2回保持しているが、ifステートメントの配置を誤っているため、1回だけリリースすることです。最初の実行で2回キャッチされます。どちらのifステートメントでも、コードは1回だけリリースします。

ifミューテックスを1回だけキャプチャするように、を再編成する必要があります。

bool captured = true;
if (!mutex.WaitOne(1000, false))
{
        Console.WriteLine("First check - some one locked the mutex");
        captured = false;
}
if (!captured && !mutex.WaitOne(3000, false))
{
        Console.WriteLine("Second check- some one locked the mutex");
        captured = false;
}
if (captured)
{
        Console.WriteLine("I got the mutex");
        Console.WriteLine("sleeping");
        Thread.Sleep(3000);
        Console.WriteLine("Awaking and Releasing mutex");
        mutex.ReleaseMutex();
}
于 2012-05-10T18:39:17.103 に答える
-2

あなたの問題はusing (var mutex = new Mutex(false, "mySpecialMutex"))線から生じていると思います。最初のスレッドが終了すると、ミューテックスオブジェクトが破棄され、エラーが発生する可能性があると思います。

可能であれば、mutexをそのメソッドの外部の(静的)クラス変数として宣言することをお勧めします。次に、スレッドを開始する前に手動でインスタンス化し、スレッドが完了したら破棄します。

于 2012-05-10T18:04:06.437 に答える