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?
All you have to do is assign a value both to a Hidden Input control's value and to a session variable in the Page Load event and on postback, check the value of the local variable against the value in the session variable.
Unfortunately though, even with a finallyblock 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.
Early on, to prevent your application from running multiple times, there were generally two different approaches: Search for a "mutex" created by your app. There are other ways, but these two are the most popular I've seen. They both still work.
11 You can use the mutex in the same way. That is, just use the createdNew flag to determine if yours is the first instance. No need to synchronize on the mutex. So the EventWaitHandle approach is no better or worse than the Mutex approach. You could use Semaphore, too.
While reading about the threading and synchronizing topics in Delphi I found the TMutex class introduced way back in Delphi XE. I decided to put it to use, if for no other reason than for educational purposes. It turns out I like it better as it's more object-oriented.
It is more usual and convenient to use Windows events for this purpose. E.g.
static EventWaitHandle s_event ; bool created ; s_event = new EventWaitHandle (false, EventResetMode.ManualReset, "my program#startup", out created) ; if (created) Launch () ; else Exit () ;
When your process exits or terminates, Windows will close the event for you, and destroy it if no open handles remain.
Added: to manage sessions, use Local\
and Global\
prefixes for the event (or mutex) name. If your application is per-user, just append a suitably mangled logged-on user's name to the event name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With