27

Possible Duplicate:
What is the correct way to create a single instance application?

I have a Winforms app, which launches a splash screen via the following code:

Hide(); bool done = false; // Below is a closure which will work with outer variables. ThreadPool.QueueUserWorkItem(x => { using (var splashForm = new SplashScreen()) { splashForm.Show(); while (!done) Application.DoEvents(); splashForm.Close(); } }); Thread.Sleep(3000); done = true; 

The above is in the main form's codebehind and called from the load event handler.

However, how can I ensure that only one instance of the application will load at a time? In the load event handler of the main form, I could check if the process list is on the system (via GetProcessesByName(...)), but is there a better method?

Using .NET 3.5.

1
  • 1
    You should call Application.Run(splashForm) instead of a DoEvents() loop. Commented Jun 26, 2011 at 19:34

2 Answers 2

67

GetProcessesByName is slow way of checking if another instance is running. The fastest and elegant method is using mutex:

[STAThread] static void Main() { bool result; var mutex = new System.Threading.Mutex(true, "UniqueAppId", out result); if (!result) { MessageBox.Show("Another instance is already running."); return; } Application.Run(new Form1()); GC.KeepAlive(mutex); // mutex shouldn't be released - important line } 

Please also bear in mind that the code you presented is not the best approach. As it was advised in one of comments calling DoEvents() in a loop is not the best idea.

Sign up to request clarification or add additional context in comments.

5 Comments

GC.KeepAlive(mutex); - doesn't work for me by some reasons. I was forsed to use private static mutex;
I may be wrong, but shouldn't 'GC.KeepAlive(mutex);' line be before 'Application.Run(new Form1());'? 'Application.Run()' method starts the program's message loop and does not return until 'Form1' is closed.
@AlexB.: no, this is on purpose. The goal is to prevent mutex from being released, which can occured when a new form is opened and Form1 is closed. Before Form1 is closed there is no risk of mutex being released
in if block, putting "application.exit()" instead of "return ", works form me, but i put the mutex check in the form1's form_load .
Why some people recommend use mutex.ReleaseMutex(), what's the difference between GC.KeepAlive(mutex) ?
35
static class Program { // Mutex can be made static so that GC doesn't recycle // same effect with GC.KeepAlive(mutex) at the end of main static Mutex mutex = new Mutex(false, "some-unique-id"); [STAThread] static void Main() { // if you like to wait a few seconds in case that the instance is just // shutting down if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false)) { MessageBox.Show("Application already started!", "", MessageBoxButtons.OK); return; } try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } finally { mutex.ReleaseMutex(); } // I find this more explicit } } 

One note about the some-unique-id -> this should be unique on the machine, so use something like your company name / application name.

Edit:

http://sanity-free.org/143/csharp_dotnet_single_instance_application.html

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.