Использование именованного мьютекса - PullRequest
3 голосов
/ 11 мая 2009

У меня есть два экземпляра, работающие с одной и той же службой Windows. Они проверяют здоровье друг друга и сообщают, если какая-либо проблема найдена. У меня есть критическая работа, которую нужно выполнить, поэтому я запускаю ее с отказоустойчивым подходом, она запускается в Master, а если Master не отвечает, она запускается в slave. Эта работа должна общаться через определенный последовательный порт, я пытаюсь использовать 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);

А потом в работе JobWrapper

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 ]

4 голосов
/ 11 мая 2009

У меня недавно была похожая проблема.

Дизайн класса Mutex немного странный / отличается от обычных классов в .NET.

Использование OpenMutex для проверки существующего Mutex не очень хорошо, так как вы должны поймать исключение.

Лучше всего использовать

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

конструктор и проверьте значение, возвращаемое createdNew.

0 голосов
/ 13 мая 2009

Я заметил, что mutex.ReleaseMutex () не сразу освобождает мьютекс. Мне пришлось вызвать GC.Collect ()

0 голосов
/ 11 мая 2009

Вы нигде не проверяете возвращаемое значение из runJobWrapper - это намеренно? В любом случае не очевидно, что на самом деле означает возвращаемое значение. Кроме того, вы действительно не должны ловить каждое исключение, которое OpenExisiting может выдать - Недостаточно памяти? Переполнение стека? и т. д. и т. д. Просто поймайте того, с кем хотите иметь дело.

Кроме того, ваш код выглядит несколько хрупким - я не удивлюсь, если у вас есть условия гонки.

...