3

I am currently using a mutex like so (which in turn is a fork of this SO answer):

bool onlyInstance;
using (Mutex mutex = new Mutex(true, "Global\\mutexname", out onlyInstance))     
{
   try
   {
      if (onlyInstance)
      {
          // single instance code
      }
   }
   finally
   {
      mutex.ReleaseMutex();
   }
}

If I'm not wrong, using uses a try-finally internally, so is the mutex.ReleaseMutex() inside the finally redundant since the using would dispose off the mutex anyway? (Assuming a mutex dispose also releases it)

Community
  • 1
  • 1
reggaemahn
  • 6,272
  • 6
  • 34
  • 59
  • 4
    The question [Why doesn't mutex get released when disposed?](http://stackoverflow.com/q/25432596/15498) obliquely answers your question and gives a lot more background. – Damien_The_Unbeliever Jan 20 '16 at 10:03
  • Not redundant but not a general pattern either. Should other threads continue as normal when this one crashes? If not, keep the Release but without the try/finally. – H H Jan 20 '16 at 10:08
  • @HenkHolterman Yes, other threads need to continue execution even if this crashes. – reggaemahn Jan 20 '16 at 10:10

2 Answers2

3

Your assumption that disposing of a Mutex release the mutex is wrong. Disposing of the mutex just tells the OS to close the mutex, nothing more.

It's your job to track the use of your mutex. Specifically a thread that acquires a mutex must release the mutex (on the same thread), otherwise you end up with an abandoned mutex. This is actually a Windows requirement, not a .NET one.

Sean
  • 60,939
  • 11
  • 97
  • 136
2

The code run when Dispose method is called is:

protected virtual void Dispose(bool explicitDisposing)
{
    if (this.safeWaitHandle != null)
    {
        this.safeWaitHandle.Close();
    }
}

The one executed by ReleaseMutex is:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public void ReleaseMutex()
{
    if (!Win32Native.ReleaseMutex(base.safeWaitHandle))
    {
        throw new ApplicationException(Environment.GetResourceString("Arg_SynchronizationLockException"));
    }
    Thread.EndCriticalRegion();
    Thread.EndThreadAffinity();
}

So your code isn't redundant

Matteo Umili
  • 3,412
  • 1
  • 19
  • 31