2017-01-13 4 views
0
using System.Collections.Concurrent; 
using System.Threading; 

namespace Examino.Infrastructure 
{ 
    public class MutexProviderService : IMutexProviderService 
    { 
     private readonly ConcurrentDictionary<string, object> mutexCollection; 

     public MutexProviderService() 
     { 
      mutexCollection = new ConcurrentDictionary<string, object>(); 
     } 

     public void Enter(string key) 
     { 
      Monitor.Enter(GetMutex(key)); 
     } 

     public void Exit(string key) 
     { 
      Monitor.Exit(GetMutex(key)); 
     } 

     public object GetMutex(string key) 
     { 
      return mutexCollection.GetOrAdd(key, (s) => new object()); 
     } 
    } 

    public interface IMutexProviderService 
    { 
     object GetMutex(string key); 
     void Enter(string key); 
     void Exit(string key); 
    } 
} 

私は、複数のTPLタスクによって、このクラスをテストし、なぜ、Monitor.Enter/Exitはlock()ステートメントと比較して信頼できないのですか?

lock (mutexProviderService.GetMutex(lockName)) {} 

が確実にクリティカルセクションと

mutexProviderService.Enter(lockName); 
try { } 
finally 
{ 
    mutexProviderService.Exit(lockName); 
} 

が信頼できないロックしてご覧ください。同じインスタンス引数で確実に呼び出されるEnter/Exitを手動で呼び出すと何が問題になりますか? P.P. MSDNの名前付きミューテックスコードは、このクラスよりもはるかに大きく複雑です。

+5

あなたはそれが信頼できないことは何を意味するのですか?このコードがどのように失敗しているかを示すテストシナリオがありますか? –

+0

'{}'ブロック内に何が入っているか分かりませんが、それを知るのは難しいです。最も明白な問題は、 'Enter'と' Exit'呼び出しの間に何かが 'lockName'を変更した場合です。 –

+2

"信頼できません"は問題ではありません。何がうまくいかないのか、これが信頼できないと判断するのかを明確にしてください。自分の投稿を読んでいる人が何が起こっているか、失敗しているか、エラーメッセージ、コードが実行されているかなどを知っているかどうかを確認する必要があります。 – nos

答えて

0

これは(this記事を読んで)実際にあなたの質問への答えではありませんが、C#4.0から始まる、lockは、次のコードを生成します。

bool lockWasTaken = false; 
var temp = obj; 
try 
{ 
    Monitor.Enter(temp, ref lockWasTaken); 
    { body } 
} 
finally 
{ 
    if (lockWasTaken) Monitor.Exit(temp); 
} 
+0

それに応じてmutexProviderServiceが更新されました。 – AlexNG

関連する問題