Geeks With Blogs
Chris Falter .NET Design and Best Practices

Recently a friend asked me how you might create a Windows Forms application that only allows a single instance per computer.  A print driver might make use of this functionality, for example, to launch a print job management dialog whenever a document prints.  Never having needed this sort of functionality before, my initial answer wasn't very helpful.  But being both curious and disinclined to back down from a technical challenge, I just had to figure this one out.

As I was looking for an inter-process synchronization mechanism, I came across the Semaphore and Mutex in the System.Threading namespace.  A semaphore can be used to manage a pooled resource (memory buffer, thread pool, connection pool, etc.) by tracking the number of available resources.  You instantiate a semaphore with an invariant maximum corresponding to the quantity of pooled resource entities (e.g., the number of database connections).  Whenever a thread wants to use the resource, it calls .WaitOne() on the appropriate semaphore and blocks until the semaphore count is greater than zero.  If the count is positive when the call is made, the thread will not need to block at all. 

When a thread enters a semaphore, the semaphore decrements its count by one.  The calling thread is responsible for calling the semaphore's .Release() method when it has completed using the resource.  This allows the semaphore to increment its count--and as a result, gives another thread access to the pooled resource.  You must call Release() inside of a finally block as soon as feasible in your codepath; my testing shows that the CLR will not release an unreleased semaphore when the semaphore reference goes out of scope, or even when the thread of execution terminates.

What we need, then, is a semaphore that has a maximum count of one (since we want only one instance of our application to be running) and will increment its count no matter how the thread that entered it terminates.  Happily, this would be a pretty good one-sentence description of the Mutex class.  The thread that calls WaitOne on a mutex ("mutual exclusion") gains ownership when it enters the mutex.  It can release the mutex at any time by calling the ReleaseMutex method, but should it fail to do so (whether by logic error or run-time failure) before it terminates, the CLR will release the mutex on its behalf.  As a result, the mutex should prove more reliable for our purposes.

Here is the singleton code in a nutshell:

using System;
using System.Windows.Forms;
using System.Threading;

namespace MutexTest
{
    
static class Program
    {
        [
STAThread]
        
static void Main()
        {
            
Application.EnableVisualStyles();
            
Application.SetCompatibleTextRenderingDefault(false);

            
// make sure no other instances of this app are running
            bool mutexIsAvailable = false;
            
Mutex m = null;
            
try
            {
                m =
new Mutex(true, "MutexTest.Singleton");
                mutexIsAvailable = m.WaitOne(1,
false); // wait only 1 ms
            }
            
catch (AbandonedMutexException)
            {
                
// don't worry about the abandonment;
                // the mutex only guards app instantiation
                mutexIsAvailable = true;
            }
            
if (mutexIsAvailable)
            {
                
try
                {
                    
Application.Run(new Form1());
                }
                
finally
                {
                    m.ReleaseMutex();
                }
            }
        }
    }
}

One of three things can happen when the Main() thread calls m.WaitOne(1, false):

  1. If the mutex is unowned (or becomes unowned within one millisecond), mutexIsAvailable is true and the thread enters/owns the mutex.
  2. If the mutex remains owned by another instance of the Windows Form app for the one millisecond duration, mutexIsAvailable is false.
  3. If the mutex is available because another instance abandoned it without releasing it, the method throws an AbandonedMutexException.  In this case, the thread owns the mutex and may safely launch the application instance, so it sets mutexIsAvailable true.

If the Main thread owns the mutex, it runs the application, using a try/finally block in order to guarantee a call to ReleaseMutex.  While strictly speaking it is not necessary to call ReleaseMutex (the CLR will do so on the thread's behalf when it terminates), I have written the code this way in order to maintain a best practice.  In some other situation, the thread that enters the mutex might continue performing more work (or enter a suspended state) after finishing its use of the resource and might not call ReleaseMutex, so it's a good idea to write the code in this fashion.

What do you think?  Is this code helpful?  Do you have any suggestions for improvement?  Leave a comment!

Posted on Friday, June 6, 2008 9:31 AM Coding Practices and Design Patterns | Back to top


Comments on this post: How To Create a Windows Form Singleton

# re: How To Create a Windows Form Singleton
Requesting Gravatar...
Works like a charm, thanks!
Left by Andreas on Oct 05, 2009 8:23 AM

# re: How To Create a Windows Form Singleton
Requesting Gravatar...
How about implementing the singleton pattern for showing/hiding window forms?
Left by Maulik on Nov 26, 2010 2:34 AM

# re: How To Create a Windows Form Singleton
Requesting Gravatar...
I am also in favor of implementing singleton pattern
Left by Abhishek Goenka on May 24, 2012 9:20 AM

Your comment:
 (will show your gravatar)


Copyright © Chris Falter | Powered by: GeeksWithBlogs.net