2009-03-13 14 views
8

これは過度ではないでしょうか?私は検索し、C#herehereの相互排除とロックについて異なる投稿を見つけました。

例:
私たちのアプリでは、複数の再接続スレッドを回す機能があり、このスレッド内ではMutexlockを使用しています。 lockはこのコードセクションへのアクセスをブロックし、connectが他のスレッドによって更新されないようにしませんか?C#のロックとミューテックスを一緒に使用する必要があります

bool connect = false; 
Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key); 

try 
{ 
    lock(site) 
    { 
     if(site.ContainsKey(key)) 
     { 
     siteInfo = (SiteInfo)site[key]; 
     if(reconnectMutex.WaitOne(100, true)) 
     { 
      connect = true; 
     } 
     } 
    } 

    if (connect) 
    { 
     // Process thread logic 
    } 
} 
catch 
{} 

reconnectMutex.ReleaseMutex(); 

詳細:
これは、Webガーデンで実行されていないASP.NETのWebサービスです。

答えて

11

Mutexは名前を持っているため、同じマシン上のすべてのプロセスを停止しますが、ロックは同じプロセス内の他のスレッドのみを停止します。私はそのコードサンプルから、なぜあなたは両方の種類のロックが必要なのか分かりません。単純なロックを短時間保持することは良い方法ですが、より重いプロセス間のmutexはおそらく長い(重複している)期間にロックされます!ミューテックスを使用する方が簡単です。おそらく、プロセス間ロックが本当に必要かどうかを知るために。

ところで、catch {}は、このシナリオでは絶対に間違ったことです。 finally { /* release mutex */ }を使用してください。彼らは非常に異なっています。キャッチは、それが必要以上の例外のはるかに多くの種類を飲み込むだろう、とも低レベルなどのメモリの破損、アクセス違反などの例外ので、代わりのに応じて実行するようにネストされて最終的にハンドラが発生します。

try 
{ 
    // something 
} 
catch 
{} 

// cleanup 

あなたは持っている必要があります。

try 
{ 
    // something 
} 
finally 
{ 
    // cleanup 
} 

そして、あなたが回復することができ、特定の例外がある場合は、あなたがそれらをキャッチすることができます:

try 
{ 
    // something 
} 
catch (DatabaseConfigurationError x) 
{ 
    // tell the user to configure the database properly 
} 
finally 
{ 
    // cleanup 
} 
+0

それに応じてマシン固有の名前を付ける必要があります。 –

+0

良い点、私はうまくいけば最初の文でそれを明らかにした。 –

+0

catch文を削除して最後に置き換えるべきだと言っていますか? –

3

を「ロック」基本的にはありますMontor.Enter/Exitの構文砂糖。ミューテックスはマルチプロセスロックです。

非常に異なる動作をします。異なるアプリケーションをブロックするように設計されているため、同じアプリケーションやメソッドで両方を使用することには問題ありません。

しかし、あなたのケースでは、あなたはセマフォーとモニターを調べる方が良いかもしれないと思います。プロセス間でロックする必要があるようには聞こえないので、おそらくこの状況ではより良い選択です。

1

本当にこれに答えるには十分な情報がありませんでした。 Earwickerがすでに述べたように、Mutexではプロセス間で同期をとることができます。したがって、同じアプリケーションの2つのインスタンスを実行している場合は、アクセスをシリアライズできます。たとえば、外部リソースを使用する場合にこれを行うことができます。

これで、サイトをロックすると、同じプロセス内の他のスレッドによるアクセスからサイトが保護されます。これは、他のメソッド/スレッドが何をしているかによって異なります。今、これがサイトがロックされている唯一の場所であれば、それは残酷だと思うでしょう。

2

他の人が指摘しているように、Mutexはプロセス間でロックし、ローカルロック(Monitor)は現在のプロセスが所有するスレッドのみをロックします。しかし...

あなたが示したコードはかなり深刻なバグを持っています。最後に無条件にMutexを解放しているようです(つまり、reconnectMutex.ReleaseMutex())、site.ContainsKey()trueを返した場合にのみMutexが取得されます。

もしsite.ContainsKeyfalseを返すならば、呼び出し元のスレッドがMutexを所有していないため、Mutexを解放するとApplicationExceptionをスローします。

+0

ありがとうございます - 私はこれを投稿した後、そのバグを発見しました。なぜアプリが閉鎖したのかわからなかった。それが問題だった。 –

関連する問題