2013-04-26 78 views
0

我有一個.net 3.5/c#/ wpf應用程序,我不希望用戶能夠運行多個實例。所以,我用我的app.xaml.cs以下單個實例應用程序AbandonedMutexException

protected override void OnStartup(StartupEventArgs e) 
{ 
    const string mutexName = "Local\\MyApp.SingleInstance"; 
    try 
    { 
     // Create a new mutex object with a unique name 
     _mutex = new Mutex(false, mutexName); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message + "\n\n" + ex.StackTrace + 
        "\n\n" + "Application Exiting…", "Exception thrown"); 
     Current.Shutdown(); 
    } 

    if (_mutex.WaitOne(0, false)) 
    { 
     base.OnStartup(e); 
    } 
    else 
    { 
     MessageBox.Show("app is already open", "Error", MessageBoxButton.OK, MessageBoxImage.Information); 
     Current.Shutdown(); 
    } 
    //...show mainwindow or load app 
} 

我的問題是,我的一些用戶的報告這一異常: 例外:等待完成因放棄的互斥體。 類型:System.Threading.AbandonedMutexException

我不能在本地重現這個,所以我很難找出發生了什麼。

會增加

finally 
{ 
    _mutex.ReleaseMutex(); 
} 

後,我的try/catch可能幫助?

+1

你絕對應該有一個'試... finally'。請參閱http://stackoverflow.com/q/635640/56778,尤其是問題中的第二個代碼示例。 – 2013-04-26 01:15:01

+0

謝謝,非常有幫助。這有助於解釋約翰的答案。 – danSiebes 2013-04-26 01:28:10

+0

另外,要明確的是,'ReleaseMutex'應該只在應用程序關閉時調用。 – jnm2 2015-12-30 14:04:40

回答

0

如何使用:

using (var mutex = new Mutex(false, mutexName)) 
{ 
    if (mutex.WaitOne(0, false)) 
    { 
     base.OnStartup(e); 
    } 
    else 
    { 
     MessageBox.Show("app is already open", "Error", MessageBoxButton.OK, MessageBoxImage.Information); 
     Current.Shutdown(); 
    } 
} 
+1

謝謝你的回答!出於我自己的理解,是這樣的想法:如果我使用using語句,互斥對象將被正確處置,我不需要擔心調用.ReleaseMutex? – danSiebes 2013-04-26 01:14:36

+0

是的,就是這樣。一般來說,如果它實現了'IDisposable',那麼把它放到一個'using'塊中。這當然是一種簡化,但幾乎是事實。 – 2013-04-26 01:25:07

+0

-1完全錯誤。您必須釋放互斥鎖,並且必須在調用'WaitOne'的同一線程上釋放它; '處置'不*做*。你應該確實使用using塊,但是立即在'WaitOne'成功塊內,'try ... finally'應該使用'finally'塊中的'ReleaseMutex'來設置。請參閱[爲什麼Mutex在處置時不會被釋放?](https://stackoverflow.com/questions/25432596/why-doesnt-mutex-get-released-when-disposed) – jnm2 2015-12-30 13:53:46