2017-06-24 166 views
-1

我有一臺計算機上運行的多實例應用程序。我想實現下面的僞代碼在C#:嘗試鎖互斥鎖或等待,直到解鎖

Mutex mutex = new Mutex(false, "SomeMutex"); 
while (true) 
{ 
    if (CheckIfCanDoSomething()) 
    { 
     if (mutex.WaitOne(TimeSpan.Zero)) 
     { 
      // I am the first instance that can do the task 
      DoSomething(); 
      mutex.ReleaseMutex(); 
     } 
     else 
     { 
      // Some other instance was first, wait until it has finished 
      mutex.WaitUntilUnlockedWithoutLockingIt(); 
      DoSomethingElse(); 
     } 
    } 
} 

基本上,我有一個應用程序的多個實例,那就是不斷地檢查一些條件是否滿足(CheckIfCanDoSomething)做某事(DoSomething)。問題是當滿足條件時,應用程序只有一個實例應該執行此任務。 CheckIfCanDoSomething方法將返回true,直到DoSomething任務完成。

我怎麼能達到mutex.WaitUntilUnlockedWithoutLockingIt()邏輯?

+0

你怎麼實現multinstance鎖定?數據庫,文件,註冊表? – eocron

+0

@eocron命名互斥體 – Darxis

+0

你的僞代碼沒有獲取鎖定 – eocron

回答

1

那麼,你顯然在你的僞代碼中有錯誤。其實我本來創建Mutext方法擴展,將描述關鍵部分:

public static void InCritical(this Mutex m, Action action) 
{ 
    m.WaitOne(); 
    try 
    { 
     action(); 
    } 
    finally 
    { 
     m.ReleaseMutext() 
    } 
} 

而且使用這樣的:

Mutex mutex = new Mutex(false, "SomeMutex"); 
while (true) 
{ 
    if (CheckIfCanDoSomething()) 
    { 
     mutex.InCritical(()=> 
     { 
      if (CheckIfCanDoSomething()) 
      { 
       DoSomething(); 
      } 
     }); 
     //at this point just recheck in while(true) 
    } 
    else 
    { 
     DoSomethingElse(); 
    } 
} 
+0

這是一個很好的答案,兩次調用CheckIfCanDoSomething,但不幸的是,必須完成對「DoSomething」的調用'CheckIfCanDoSomething'返回true後儘可能快。在我的情況下,這是一個HTTP請求,所以我不能承受這樣的延遲。 – Darxis

+1

那麼你有兩個選擇:1)取消第二次檢查,不關心連續做兩次DoSomething(),這可能會導致嚴重的不可糾錯錯誤。 2)跨應用程序緩存全局CheckIfCanDoSomething()的值。 – eocron

+0

我會嘗試使用共享內存(例如MemoryMappedFile)進行這種緩存,它應該足夠快。 – Darxis