Only one application instance
Sometimes we need to disallow starting multiple instances of our application (for example, it make sense for music players, applications for Windows Tray, etc.). The easiest and, probably, the most proper way is to use Mutex - a synchronization primitive.
To simplify Mutex
using for checking application instances, I've written a tiny helper class:
public class UniqueInstanceChecker
{
private readonly Mutex _mutex;
private readonly bool _owner;
public UniqueInstanceChecker(string uniqueId)
{
_mutex = new Mutex(true, uniqueId, out _owner);
}
public bool IsAlreadyRunning()
{
return !_mutex.WaitOne(TimeSpan.Zero, true);
}
public void Release()
{
if (_owner)
{
_mutex.ReleaseMutex();
}
}
}
How to use it? Just create an instance of this class in the application main class (for example, in the Program
, MainForm
, etc.) - where startup object is located. Pass an identifier of your application to constructor's parameter uniqueId
. It's a system-wide Mutex
Id
that we will check in different application instances. It can be any string, but it should be unique for our application. A good practice is to use a GUID
.
Then, on the application start we need to call method IsAlreadyRunning()
. It returns true
if some application instance is already running. In this case we simply close the current one.
And the last, just before the application close, we should call method Release()
.
How does it work? When the first application instance starts, it creates a Mutex
object and becomes its owner. The Mutex
is in signaled state. Then we call IsAlreadyRunning()
, and WaitOne()
inside method makes a request for Mutex
. Mutex
was just created so the request completes successfully and switches Mutex
to non-signaled state.
When we start another application, we create Mutex
again. Since it already exists in the system, application instance can't become Mutex
owner and uses already existing one. Method WaitOne()
fails this time because Mutex
is already in a non-signaled state.
When we call Release()
in the application that owns Mutex
, it releases Mutex
and switches it to the signaled state back. All other application instances skip Mutex
releasing inside Release()
method.