2013-01-17 9 views
7

私は以下のような状況があります。オブジェクトへのアクセスを相互に排除したい。ロックとモニタを同じオブジェクトで安全に使用できますか?

これまでのところ私はnormaly今、私はまた、別のスレッドから呼び出すことができるメソッドを持って

object lockObject = new object(); 
... 

method1: lock(lockObject) { CODE1 } 

ロックオブジェクトを使用します。未知の時間のためにブロックされるべきではなく、定義された時間内に答えが得られるはずです。私は、モニターを使用します。この場合、

、今

method2: 
try{ 
    Monitor.TryEnter(lockObject , 20000, ref lockTaken); 
    if (lockTaken) {CODE2} 
} 
catch(...){...} 
finally 
{ 
    if (lockTaken) Monitor.Exit(timerLock); 
} 

のように私の質問です:ロックすることができ、モニターはlockobjectが同じであれば、このような方法で混合し、相互に排除し、または希望しますすべてのロックをモニターに変更する必要があります。

したがって、同じトークンが両方とも「ロック」されているか、モニターがオブジェクトのロックとロックの別のトークンを作成しますか?

私は、アプリケーションが両方のコードで同時に実行されているのを見ることはできません。しかし、CODE1とCODE2が並行して実行されるタイミングの問題が存在するかどうかはわかりません。

+1

私はあなたの痛みを感じます。私はしばしば 'lock'キーワードが何とかタイムアウトになることを願っています –

答えて

6
lock (sync) 
{ 
    return World(); 
} 

中間言語でこの行を見てみましょう。

L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object) 
L_000c: call int32 Hello::World() 
L_0011: stloc.0 
L_0012: leave.s L_001b 
L_0014: ldloc.1 
L_0015: call void [mscorlib]System.Threading.Monitor::Exit(object) 

だから大丈夫です。彼らは技術的に同等です。

+0

最近のバージョンのcscは、.NET 4以上をターゲットにすると、これとは異なるILを持つことに注意してください。 –

+0

ありがとうございます。大まかな説明のためだけにしました。 –

5

はロックとlockobjectが同じであれば、このような方法で混合することが監視し、相互

はい、それは完全に安全で除外し、それが動作しますすることができます。

lock { }ステートメントは、Monitor.Enter()およびMonitor.Exit()の呼び出しに書き換えられます。それはちょうど短い手で、using() {}のステートメントによく似ています。 MSDNから

lock (x) ... 

がFX4に、

System.Threading.Monitor.Enter(x); 
try { 
    ... 
} 
finally { 
    System.Threading.Monitor.Exit(x); 
} 

コメントどおりになり、後でそれがMonitor.TryEnter()を使用することができます。しかし、上記の単純なバージョンはあなたの質問に答えます。

+2

または.NET 4+をターゲットとするときはMonitor.TryEnter。 –

関連する問題