I'm using this code to prevent a second instance of my program from running at the same time, is it safe?
Mutex appSingleton = new System.Threading.Mutex(false, "MyAppSingleInstnceMutx");
if (appSingleton.WaitOne(0, false)) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
appSingleton.Close();
} else {
MessageBox.Show("Sorry, only one instance of MyApp is allowed.");
}
I'm worried that if something throws an exception and the app crashes that the Mutex will still be held. Is that true?
In general yes this will work. However the devil is in the details.
Firstly you want to close the mutex in a finally
block. Otherwise your process could abruptly terminate and leave it in a signaled state, like an exception. That would make it so that future process instances would not be able to start up.
Unfortunately though, even with a finally
block you must deal with the potential that a process will be terminated without freeing up the mutex. This can happen for instance if a user kills the process through TaskManager. There is a race condition in your code that would allow for a second process to get an AbandonedMutexException
in the WaitOne
call. You'll need a recovery strategy for this.
I encourage you to read up on the details of the Mutex class. Using it is not always simple.
Expanding upon the race condition possibility:
The following sequence of events can occur which would cause a second instance of the application to throw:
WaitOne
call.AbanonedMutexException
.