2009-05-11 3 views
1

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

ответ

3

У меня была аналогичная проблема в последнее время.

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

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

Лучший подход заключается в использовании конструктор

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

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

+0

Там есть метод TryOpenExisting. –

+0

Он появился в .NET 4.5. –

0

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

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

+0

первая часть была написана вручную scalled вниз вариант ... я пропустил это ... отредактировал вопрос –

0

я заметил, что mutex.ReleaseMutex() не отпуская семафор immediately..I пришлось вызвать GC.Collect()

+1

Осторожно о ваших ожиданиях, .NET GC не детерминирован – annakata

+1

mutex.ReleaseMutex() не Dispose()! Он не освобождает ресурсы, удерживаемые мьютексом, но он «разблокирует» мьютексы, поэтому другой процесс может получить его через Mutex.WaitOne(). Для утилизации Mutex используйте mutex.Close(). Пожалуйста, ознакомьтесь с документацией. – Emiswelt

Смежные вопросы