У меня есть следующий код:
using (Mutex mut = new Mutex(false, MUTEX_NAME))
{
if (mut.WaitOne(new TimeSpan(0, 0, 30)))
{
// Some code that deals with a specific TCP port
// Don't want this to run at the same time in another process
}
}
Я установил точку останова в блоке if и запустил тот же код в другом экземпляре Visual Studio. Как и ожидалось, блоки вызовов .WaitOne. Однако, к моему удивлению, как только я продолжу в первом экземпляре, а блок using завершается, я получаю исключение во втором процессе о заброшенном Mutex.
Исправление состоит в вызове ReleaseMutex:
using (Mutex mut = new Mutex(false, MUTEX_NAME))
{
if (mut.WaitOne(new TimeSpan(0, 0, 30)))
{
// Some code that deals with a specific TCP port
// Don't want this to run twice in multiple processes
}
mut.ReleaseMutex();
}
Теперь все работает так, как ожидалось.
Мой вопрос: Обычно точка IDisposable очищает любое состояние, в которое вы вставляете вещи. Возможно, у меня есть несколько ожиданий и выпусков в блоке using, но когда дескриптор Mutex расположен, не должен ли он автоматически выпускаться? Другими словами, почему мне нужно вызывать ReleaseMutex, если я в блоке using?
Я также обеспокоен тем, что если код внутри блока if выйдет из строя, я останусь мьютексами, лежащими вокруг.
Есть ли какая-либо польза для размещения Mutex в блоке using? Или, должен ли я просто обновить экземпляр Mutex, обернуть его в try/catch и вызвать ReleaseMutex() в блоке finally (в основном реализовать то, что я думал Dispose())