2011-06-26 15 views
17

Olası Çoğalt sağlanması:
What is the correct way to create a single instance application?tek uygulama instance'a

Aşağıdaki kodu aracılığıyla bir açılış ekranı başlattı bir Win uygulaması vardır:

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 Yukarıdaki ana formun codebehind ve yük olay işleyicisinden çağrılır. Ancak, uygulamanın yalnızca bir örneğinin aynı anda yüklenmesini nasıl sağlayabilirim? Ana formun yük olay işleyicisinde, süreç listesinin sistemde olup olmadığını kontrol edebilirim (GetProcessesByName (...) yoluyla), ancak daha iyi bir yöntem var mı?

.NET 3.5'i kullanma.

+1

Sen çağırmalıdır 'Application.Run (splashForm)' yerine 'DoEvents()' döngü. – SLaks

cevap

50

GetProcessesByName, başka bir örneğin çalışıp çalışmadığını kontrol etmenin yavaş bir yoludur. En hızlı ve zarif yöntem muteksi kullanıyor:

[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 
    } 

ayrıca sunulan kod iyi yaklaşım olmadığını göz önünde bulundurunuz. Bir döngü içinde DoEvents() çağırmak yorumlardan birinde tavsiye edildiği gibi en iyi fikir değildir. Bazı benzersiz-id yaklaşık

+0

GC.KeepAlive (mutex); - Bazı nedenlerle benim için çalışmıyor. özel statik muteksini kullanmak için kullanıldıktan sonra; – monstr

+0

Yanlış olabilir, ancak 'GC.KeepAlive (mutex);' satır önce Application.Run (yeni Form1()); '? 'Application.Run()' yöntemi, programın ileti döngüsünü başlatır ve 'Form1' kapanana kadar geri dönmez. –

+0

@AlexB .: hayır, bu amaca hizmet ediyor. Amaç, muteks'in yeni bir form açıldığında ve Form1 kapatıldığında ortaya çıkmasını önlemek içindir. Form1 kapatılmadan önce, muteks'in – michalczerwinski

16
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 
    } 
} 

Bir not -> Bu makinede benzersiz olması, bu nedenle şirket adı/uygulama adı gibi bir şey kullanmalıdır.

Düzenleme:

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

İlgili konular