3

同じ Windows サービスを実行している 2 つのインスタンスがあります。彼らはお互いの状態をチェックし、問題が見つかった場合は報告します。実行する必要がある重要なジョブがあるため、フェールオーバー アプローチで実行しています。それはマスターで実行され、マスターが応答しない場合はスレーブで実行されます。このジョブは特定のシリアル ポートを介して通信する必要があります。Mutex を使用して競合状態をチェックしようとしています。私は本番環境にアクセスできないので、展開する前に自分のアプローチが問題ないことを確認したいと考えています。そのため、特定のケースで Mutex の使用が適切かどうかを提案してください。

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;
   }
}
4

3 に答える 3

5

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

クラスの設計は、Mutex.NET の通常のクラスとは少し奇妙/異なります。

を使用OpenMutexして既存のものをチェックするのMutexは、例外をキャッチする必要があるため、あまり良くありません。

より良いアプローチは、

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

コンストラクタ、およびによって返される値を確認しますcreatedNew

于 2009-05-11T08:57:17.747 に答える
0

どこからでも戻り値をチェックするつもりはありませんrunJobWrapper- これは意図的なものですか? とにかく、戻り値が実際に何を意味するのかは明らかではありません。また、スローされる可能性のあるすべての例外をキャッチするべきではありませんOpenExisiting-メモリ不足ですか?スタックオーバーフロー?などなど。正しく処理するつもりのものをキャッチするだけです。

また、あなたのコードはやや壊れやすいようです - 競合状態があっても驚かないでしょう。

于 2009-05-11T09:00:47.913 に答える
0

私は、mutex.ReleaseMutex() がミューテックスをすぐに解放していないことに気付きました..GC.Collect() を呼び出さなければなりませんでした。

于 2009-05-13T11:22:29.893 に答える