2014-08-27 52 views
-1

摘要:我該如何擺脫廢棄的互斥體?

有沒有辦法來清除一個互斥體,如果創建它的過程是死了沒有?

詳情:

我用一個互斥體,以確保只有一個我的應用程序運行的實例。

雖然測試了一些新的代碼(做自動更新),我跑了Environment.Exit(0)。在調試模式下運行時,我的互斥鎖被清理得很好。

但是,當我改變了構建以「釋放」,那麼互斥退出通話後保持周圍,爲被遺棄的標記:

Abandoned Mutex

我有雙重檢查,以確保沒有這個互斥體所依附的進程仍在運行。

現在每次運行我的應用程序時,它都認爲互斥量仍然存在,並且不會啓動我的應用程序。 (這也崩潰,因爲它試圖將消息發送到應用程序的「正在運行」的實例,以顯示自己。)

我試圖釋放這樣的互斥體:

bool createdNew; 
string applicationId = "18773:TestStudio"; 
var singleInstanceMutex = new Mutex(true, applicationId, out createdNew); 

singleInstanceMutex.Close(); // Tried ReleaseMutex() too 

當然,但只是得到它,然後釋放它。

我知道我可以重新啓動,但爲了更好地解決這種情況,在生產中發生這種情況時我正在跳轉。

如果創建它的進程已經死了並且不存在,是否有辦法清除互斥鎖?

+3

根據你的屏幕截圖,3件事仍在引用它。關閉任何3件事仍然有處理。 – 2014-08-27 23:35:15

+0

@Scott Chamberlain - 參考文獻仍然存在,但這個過程早已消失。它以不釋放參考的方式死亡。因此我的問題是如何釋放互斥鎖。 – Vaccano 2014-08-28 02:34:35

+0

@Vccano那麼你有兩種情況之一。一個腐敗的操作系統安裝,或者有一個你沒有意識到的參考就是參考。如果它真的走了,那麼計數將爲0,從失敗的進程中清除句柄在Windows 95(或98,我不記得是哪個)中修復了。可能的情況是,程序不是真的死了,當你認爲它已經死了或者其他程序(IIS,一種殺毒軟件,誰知道)正在提取句柄並且沒有完成它時,它仍然存在。 – 2014-08-28 03:40:39

回答

0

不知道這實際上回答你的問題,但這裏是我用於此目的的代碼:

// Mutex object used to determine if there are multiple instances of this program running. 
    // Note that this is a reference to a .Net Mutex object, not the Windows mutex itself. 
    private static Mutex _onlyOneInstanceMutex; 



    /// <summary> 
    /// Method to test that there is not another instance of the program already running on this 
    /// machine, or at least in this Terminal Services session or Windows Vista/Windows 7 
    /// concurrent sessions session. If there is, a message box-style localized error message is 
    /// displayed and the value false is returned. This implies that this method should not be 
    /// used in programs that are run as a Windows service. 
    /// 
    /// This implementation uses a .Net Mutex object in public storage to prevent it from being 
    /// garbage-collected. The name of the associated Windows mutex is simply the program name as 
    /// provided by the caller. Neither the .Net Mutex object nor the Windows mutex are ever 
    /// explicitly released; they remain in existence, perhaps in an "abandoned" state, until the 
    /// process that created them terminates. 
    /// </summary> 
    /// <returns>false if another instance running, otherwise true</returns> 
    [SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive", 
        Justification = "Not sure if this is correct or not.")] 
    public static bool TestOnlyOneInstance(string programName) 
    { 
    // Funny construct to prevent the Mutex from being garbage collected 
    GC.KeepAlive(_onlyOneInstanceMutex); 

    // Test if we are the first instance, and if so create the Windows mutex, making it 
    // impossible for subsequent instances to successfully create their mutex 
    bool firstInstance; 
    _onlyOneInstanceMutex = new Mutex(false, programName, out firstInstance); 
    if (firstInstance) 
     return true; 

    // Display a (possibly localized) error message, then return 
    string errorMessage = MLocalizer.GetString("Error1", 
      "Another instance of this program is already running on this machine.") + 
     "\n" + MLocalizer.GetString("Error2", 
            "You cannot run two instances at the same time.") + 
     "\n" + MLocalizer.GetString("Error3", "Please use the other instance."); 
    MessageBox.Show(errorMessage, programName, MessageBoxButtons.OK, MessageBoxIcon.Error); 
    return false; 
    } 

編輯:

唯一的區別我可以在我的代碼中看到的和你是我指定「最初擁有」爲假,而我對垃圾收集有趣。

哦,我聲明互斥體是靜態的。