2

オブジェクトの作成中にミューテックスを使用して一部のコードを同期するC#アプリケーションコードがあります。オブジェクトコンストラクターはミューテックスを取得し、オブジェクトが不要になったとき(アプリのシャットダウン中)にのみミューテックスを解放します。したがって、ミューテックスを解放する1つの場所は、オブジェクトデストラクタになります。発生した問題は、オブジェクトデストラクタでのReleaseMutex()の呼び出し中に例外が発生することがあることです。例外は、「オブジェクト同期メソッドが同期されていないコードブロックから呼び出された」です。オブジェクトデストラクタを呼び出すガベージコレクションを実行するスレッドは、そもそもミューテックス(Mutex.WaitOne(false、namedMutex))を待機するスレッドとは異なる場合があるようです。この例外を回避するために、同じスレッドでミューテックスの取得と解放を同期するにはどうすればよいですか?ご協力いただきありがとうございます!

public class MyObject
{
    static ExtDeviceDriver devDrv;
    private Mutex mut = new Mutex(false,myMutex);

    public MyObject()
    {
        mut.WaitOne();
        //Thread safe code here.
        devDrv = new ExtDeviceDriver();
    }

    ~MyObject()
    {
        mut.ReleaseMutex();
    }
}
4

1 に答える 1

4

Disposeパターンを使ってみませんか? Mutexを継承しWaitHandleWaitHandle実装しIDisposableます。を作成して使用するクラスがある場合は、IDisposableそれも実装IDisposableして適切に破棄する必要があります。GCにミューテックスを破棄させないでください。using手動でブロック内で実行するか、手動で呼び出し.Dispose()てください。このようにして、誰がいつ何をしているのかを常に知ることができます。

この投稿には、心に留めておくべき素晴らしい引用があります。

オブジェクトがIDisposableを実装している場合は、オブジェクトがどのようにクリーンアップされているかを考慮する必要があります。

IDisposableを実装するオブジェクトは、決定論的に解放する必要がある実際のリソースを保持しているため、通常はそうします。

これがまさにここで起こっていることです。

また、名前付きミューテックスを使用しているようです。名前付きミューテックスはプロセス間で使用され、オペレーティングシステムのハンドルとして管理されます。他の誰かが同じミューテックスを取得してリリースしようとしていますか?名前付きミューテックスが必要な理由はありますか?プロセスが停止し、ミューテックスが適切に処理されない場合、ミューテックスやその他のあらゆる種類の奇妙なものを放棄する可能性があるため、これらは通常、対処するのが難しいです。

于 2012-09-22T01:00:27.917 に答える