I have the following code:
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
}
}
I've set a breakpoint within the if
block, and ran the same code within another instance of Visual Studio. As expected, the .WaitOne
call blocks. However, to my surprise, as soon as I continue in the first instance and the using
block terminates, I get an exception in the second process about an abandoned Mutex.
The fix is to call 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();
}
Now, things work as expected.
My Question: Usually the point of an IDisposable
is it cleans up whatever state you put things in. I could see perhaps having multiple waits and releases within a using
block, but when the handle to the Mutex is disposed, shouldn't it get released automatically? In other words, why do I need to call ReleaseMutex
if I'm in a using
block?
I'm also now concerned that if the code within the if
block crashes, I'll have abandoned mutexes lying around.
Is there any benefit to putting Mutex
in a using
block? Or, should I just new up a Mutex
instance, wrap it in a try/catch, and call ReleaseMutex()
within the finally block (Basically implementing exactly what I thought Dispose()
would do)
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…