2009-08-19 17 views
45

オブジェクトがC#でロックされているかどうかを判断する方法はありますか?私は、クラス内のキューから読み込んでいるデザインから、クラス内のコレクションに内容をダンプする必要があります。しかし、そのコレクションは、クラス外のインターフェースからの読み書きも可能です。コレクションが書き込まれているケースもありますが、同時にコレクションに書きたい場合もあります。オブジェクトがロックされているかどうかを検出する方法はありますか?

私はそれをプログラムすることができました、例えば、デリゲートを使用して、それは醜いでしょう。

+0

はい、 ありがとうございました。それは、私がすでに思ったことをかなり確認します。 –

答えて

40

Monitor classのスタティックTryEnter methodは、値を0として使用して呼び出すことができます。ロックされている場合、呼び出しはfalseを返します。

ただし、ここでの問題は、アクセスを同期しようとしているリストがロックされていることを確認して、アクセスを同期させる必要があることです。

アクセスが同期されているオブジェクトをロックオンするオブジェクトとして使用することは、一般に悪いことです(オブジェクトの内部の詳細をあまりにも多く露出させる)。

ロックは他にもある可能性があることを覚えておいてください。リストがロックされていることが確実でない限り、そのリストでこれを呼び出すだけで無意味です。

10

Monitor.TryEnterは、オブジェクトがロックされていない場合は成功し、この時点でオブジェクトがロックされている場合はfalseを返します。ただし、暗黙のレースがあることに注意してください。このメソッドが返すインスタンスは、オブジェクトがロックされなくなる可能性があります。

6

現在、Monitor.TryEnterを呼び出して、オブジェクトがロックされているかどうかを調べることができます。 .NET 4.0 CLRチームで

は、ここで「ロック検査API」を追加する

を行っているRick Byers記事から引用されています。私たちはいくつかの簡単なAPIを

ロック検査
追加しています管理ロック(Monitors)を探索するためのICorDebugへ。たとえば、スレッドがロックを待ってブロックされている場合、現在ロックを保持している他のスレッド(およびタイムアウトがある場合)を見つけることができます。

したがって、このAPIを使用すると、
を確認できます。1)どのオブジェクトがロックを保持していますか?
2)誰がそれを待っていますか?

これが役に立ちます。

+0

興味深い。 ボブ。 –

7

時間が0のTryEnterを静的に呼び出すと、ロックが利用可能になった場合にロックが取得されないことが保証されているかどうかはわかりません。同期変数がロックされていた私は、デバッグモードでテストするためにやったソリューションは、以下を使用していました:

#if DEBUG 
// Make sure we're inside a lock of the SyncRoot by trying to lock it. 
// If we're able to lock it, that means that it wasn't locked in the first 
// place. Afterwards, we release the lock if we had obtained it. 
bool acquired = false; 
try 
{ 
    acquired = Monitor.TryEnter(SyncRoot); 
} 
finally 
{ 
    if (acquired) 
    { 
     Monitor.Exit(SyncRoot); 
    } 
} 
Debug.Assert(acquired == false, "The SyncRoot is not locked."); 
#endif 
+2

変数 'isNotLocked'の名前はかなり悪いです。 'isNotLocked'が真であるとロックを解除します。なぜなら、技術的に正しいのは、ロックが正常に取得されたときに' isNotLocked'が真となるためです。誰かがこれに取り組まなければならない場合、彼はWTFの瞬間を持つでしょう。 – ChrisWue

+2

これが実行されているスレッドがロックを所有するスレッドと同じである場合、機能しません。実際にはロックされていないときにロックがフリーであると言います。 –

4

Monitor.IsEntered

現在のスレッドが指定されたオブジェクトのロックを保持しているかどうかを決定します。
利用可能時間4.5

関連する問題