In his article about preventing multiple instances of an application, Michael Covington presents this code:
static void Main() // args are OK here, of course { bool ok; m = new System.Threading.Mutex(true, 'YourNameHere', out ok); if (! ok) { MessageBox.Show('Another instance is already running.'); return; } Application.Run(new Form1()); // or whatever was there GC.KeepAlive(m); // important! }
He explains that the GC.KeepAlive(m) is required to prevent the garbage collector from collecting the mutex early, since there are no additional references to it.
My question: will wrapping the mutex in a using do the same thing? That is, will the following also prevent the GC from pulling the rug out from under me?
static void Main() // args are OK here, of course { bool ok; using (var m = new System.Threading.Mutex(true, 'YourNameHere', out ok)) { if (! ok) { MessageBox.Show('Another instance is already running.'); return; } Application.Run(new Form1()); // or whatever was there } }
My gut reaction is that the using will work, since using is (supposed to be) equivalent to:
Mutex m = new System.Threading.Mutex(true, 'YourNameHere', out ok); try { // do stuff here } finally { m.Close(); }
And I would think that the m.Close() there would be enough to signal to the JIT compiler that there’s another reference, thus preventing premature garbage collection.
Wrapping the mutex in a
usingstatement will indeed prevent it from being garbage collected, but will also dispose of it (it callsDispose, notClose) at the end (whereasGC.KeepAlivewon’t, obviously).If the end of the method is genuinely going to be the end of the process, I don’t believe it’s likely to make any practical difference which you use – I prefer the
usingstatement on the general principle of disposing of anything which implementsIDisposable.If the mutex hasn’t been disposed when the process exits, I suspect its finalizer will take care of it – so long as other finalizers don’t hog the finalization thread beyond its timeout.
If the finalizer doesn’t take care of it, I don’t know whether Windows itself will notice that the process can’t possibly own the mutex any more, given that it (the process) doesn’t exist any more. I suspect it will, but you’d have to check detailed Win32 documentation to know for sure.