2009-05-11 22 views
1

同じWindowsサービスを実行しているインスタンスが2つあります。彼らはお互いの健康状態をチェックし、問題が見つかった場合に報告します。私は実行する必要がある重要な仕事を持っているので、フェールオーバーの方法で実行しています。それはマスターで実行され、マスターが応答していなければスレーブで実行されます。この仕事は、特定のシリアルポートを介して通信する必要があります、私は競合状態をチェックするためにミューテックスを使用しようとしています。私は生産にアクセスできないので、展開する前に私のアプローチがうまくいくことを確認したい。ですから、私のミューテックスの使用がそのケースでうまくいくかどうかをお勧めします。名前付きミューテックスの使用

if (iAmRunningInSlave) 
{ 
    HealthClient hc = new HealthClient(); 
    if (!hc.CheckHealthOfMaster()) 
     return this.runJobWrapper(withMutex, iAmRunningInSlave); 
    else 
     return true; //master is ok, we dont need to run the job in slave 
} 
return this.runJobWrapper(withMutex, iAmRunningInSlave); 

そしてrunJobWrapper

bool runJobWrapper(bool withMutex, bool iAmRunningInSlave) 
{ 
    if (!withMutex) 
     return this.runJob(iAmRunningInSlave); //the job might be interested to know 
    Mutex mutex = null; 
    string mutexName = this.jobCategory + "-" + this.jobTitle; //this will be unique for given job 
    try 
    { 
     mutex = Mutex.OpenExisting(mutexName); 
     return false; //mutex is with peer, return false which will re-trigger slave 
    } 
    catch 
    { 
     try 
     { //mean time mutex might have created, so wrapping in try/catch 
     mutex = new Mutex(true /*initiallyOwned*/, mutexName); 
     return this.runJob(iAmRunningInSlave); //the job might be interested to know where I am running 
     } 
     finally 
     { 
     if (null!=mutex) mutex.ReleaseMutex(); 
     } 
     return false; 
    } 
} 

答えて

3

私は最近、同様の問題がありました。

Mutexクラスのデザインは、.NETの通常のクラスとは少し違っています。

OpenMutexを使用して既存のMutexをチェックすると、例外をキャッチする必要があります。

より良いアプローチは

Mutex(bool initiallyOwned, string name, out bool createdNew) 

コンストラクタを使用して、createdNewから返される値をチェックすることです。

+0

)mutex.ReleaseMutexは()immediately..IはGC.Collectを(呼び出すために持っていたミューテックスを解放していなかったことに気づきました。 –

+0

.NET 4.5で登場しました。 –

0

戻り値をどこからでも確認することはありません。runJobWrapper - これは意図的ですか?とにかく戻り値が実際に意味するものは明白ではありません。また、OpenExisitingが捨てる可能性があるすべての例外をすべてキャッチしてはいけません。スタックオーバーフロー?ちょうどあなたが正しく扱うことを意味するものをキャッチする。

また、あなたのコードはやや壊れやすいと思われます。競合条件がある場合、私は驚かないでしょう。

+0

最初の部分が手書きで書かれていました...私はそれを逃しました...質問を編集しました –

0

私はTryOpenExisting方法があり

+1

.NET GCが決定的ではないことを期待しています – annakata

+1

mutex.ReleaseMutex()はDispose()ではありません!ミューテックスが保持するリソースは解放されませんが、他のプロセスがMutex.WaitOne()を使用して取得できるように、ミューテックスを「ロック解除」します。ミューテックスを廃棄するには、mutex.Close()を使用します。ドキュメントをお読みください。 – Emiswelt

関連する問題