17

I'm working on 2 Windows Services that have a common database which I want to lock (cross-process) with a system Mutex.

Now I'm wondering whether it's ok to just call WaitOne() and ReleaseMutex() in a try-finally block or should I also dispose the Mutex (e.g. in a using block). If so I guess I should always catch the AbandonedMutexException on the WaitOne() method or am I wrong here?

Koen
  • 3,626
  • 1
  • 34
  • 55
  • You need the AbandonedMutexException to tell you that the service that owns the mutex has unexpectedly terminated. In which case you *have* to stop using the dbase and wait for the other service to start up again. Using a 3rd process to act as the arbiter would be wise. – Hans Passant Aug 18 '11 at 13:17

3 Answers3

17

A mutex is a Windows kernel object (here wrapped in a .NET object).

As such, it is an unmanaged resource that should be disposed.

More accurately, the .NET object contains a HANDLE to the mutex, which must be released/disposed of somehow.

I don't trust that code sample in the Mutex class docs where the mutex object is not disposed. Although Henzi has a good point in comment: The Mutex object is static and would be either disposed by the finalizer or destroyed by the Windows kernel when the process exits.

Also, note that Close() disposes the object as well.

Of course, there's nothing wrong with keeping an existing Mutex object in your app even while you don't use it. They are light resources.

Serge Wautier
  • 21,494
  • 13
  • 69
  • 110
  • There is no code sample left, you have to link it: http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx – Oskar Kjellin Aug 18 '11 at 12:13
  • But since I'm creating Windows services I think I should not bother disposing during the "runtime" of my services (which is always). Creating a new Mutex instance with the same name every time would just wrap the same unmanaged instance right? Or will it create new unmanaged resources over and over? I could Close the mutex when one of my services is stopped to really clean it up maybe? – Koen Aug 18 '11 at 12:21
  • In the code sample, a single mutex is created, it's stored in a static field, and it's used for the whole duration of the application. Finalizers are called automatically when the application terminates. So, what would be the point of disposing that mutex? (I do agree with your point, though, that *in general* all IDisposable objects should be disposed. I just disagree on the fact that there's something missing in the code example.) – Heinzi Aug 18 '11 at 12:23
  • Serge, I think the problem is though that this mutex is going to be shared by two windows services. So BOTH have to be stopped for the finalizer to run. If something implements IDisposable, always make sure you call Dispose. – Andy Aug 18 '11 at 12:37
  • 3
    No - each process has its own HANDLE... so the finalizer only gets rid of that HANDLE... the kernel object itself is finally destroyed by Windows when there are no more HANDLEs (in this example = no more processes) to that Mutex... – Yahia Aug 18 '11 at 12:42
  • I don't get why you couldn't simply trust the finalizer in most cases. It's not like Mutexes are so expensive that you can't afford to wait until the GC runs, are they? – avl_sweden May 21 '15 at 13:31
  • @SergeWautier, I do the following, after dispose the mutex (first instance), clear the reference (myMutex = null) and call GC manually, GC.Collect() (vide @avl_sweden), this will ensure that the next instance will be the first. – antonio Mar 12 '18 at 01:43
11

According to this a named Mutex is automatically destroyed when the last process holding a HANDLE of that Mutex ends.

In non-managed terms MSDN says

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.

In .NET you should call .Close() on the Mutex - this releases the HANDLE... since every process gets its own HANDLE when accessing even the same named Mutex this is consistent practice... not calling Close() won't leave any problems behing once the process is no more (finalizers and all)...

Yahia
  • 69,653
  • 9
  • 115
  • 144
2

You need to dispose the resources which are used by the waithandle.

From the documentation:

Releases all resources used by the current instance of the WaitHandle class. (Inherited from WaitHandle.)

The waithandle uses unmanaged resources which should be disposed at the end of use.

MSDN Documentation Mutex

Peter
  • 27,590
  • 8
  • 64
  • 84