2017-08-01 45 views
2

我有一個創建互斥鎖,並立即取得所有權,然後單擊按鈕時,它會釋放一個它的過程:C#互斥總是停留在WaitOne的

Mutex req_mutex = new Mutex(true, "req_mutex"); 

...

req_mutex.WaitOne(); // not required for first click 
req_mutex.ReleaseMutex(); 

其他進程進行循環並檢查是否存在互斥,當它等待它被釋放:

bool waitingForReqMutexCreation = true; 
while (waitingForReqMutexCreation) 
{ 
     try 
     { 
      req_mutex = Mutex.OpenExisting("req_mutex", MutexRights.Synchronize); 
      waitingForReqMutexCreation = false; 
     } 
     catch (WaitHandleCannotBeOpenedException) 
     { 
      Thread.Sleep(1000); 
     } 
} 

...

req_mutex.WaitOne(); // wait for new request *********** problem here ********* 
req_mem.readFile(); // read request 
req_mutex.ReleaseMutex(); // release req mutex for more requests 

問題是互斥本來應該由按鈕,在第一過程中釋放後連的WaitOne不會繼續。

有沒有人有一個想法,爲什麼這可能是?

回答

-1

我想我找到了答案,以我自己的問題......

顯然WaitOne的操作你做不物質的量。 我取得了所有權(構造函數中的真實參數),並在同一個線程中做了一個額外的WaitOne,假設它不會受到傷害。 現在爲了釋放互斥鎖,我顯然不得不兩次調用ReleaseMutex。

我想我還可以像這樣做,直到拋出一個異常調用ReleaseMutex在環...

+0

切勿在循環中調用ReleaseMutex。如果您無法確切知道釋放互斥鎖的次數,那麼您的應用程序設計不佳。正如其他人所指出的,互斥體最初不應該是自己的。或者,您應該在初始化完成後釋放它。 **無論如何,你現在應該在做什麼。**多線程並不是你可以猜測的東西。如果你做錯了,你的應用程序不會像預期的那樣工作。 – Phil1970

1

你基本上取得互斥兩次在第一個應用程序。你可以通過在第二個應用程序運行時殺死你的第一個應用程序來看到這一點,你會得到一個AbandonedMutexException(這意味着Mutex被獲取)。用下面轉載的readline的代替按鈕點擊:

namespace Mutex_1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Mutex req_mutex = new Mutex(true, "req_mutex"); 

      String t = string.Empty; 

      while (!t.Contains("q")) 
      { 
       Console.WriteLine("input: "); 
       t = Console.ReadLine(); 

       Console.WriteLine("waiting for req_mutex"); 
       req_mutex.WaitOne(); // not required for first click 
       Console.WriteLine("releasing req_mutex"); 
       req_mutex.ReleaseMutex(); 
      } 

      Console.ReadLine(); 
     } 
    } 
} 

namespace Mutex_2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Mutex req_mutex = null; 

      bool waitingForReqMutexCreation = true; 
      while (waitingForReqMutexCreation) 
      { 
       try 
       { 
        req_mutex = Mutex.OpenExisting("req_mutex"); 
        waitingForReqMutexCreation = false; 
       } 
       catch (WaitHandleCannotBeOpenedException) 
       { 
        Console.WriteLine("req_mutex does not exist."); 
        Thread.Sleep(1000); 
       } 
      } 
      Console.WriteLine("req_mutex found"); 
      req_mutex.WaitOne(); // wait for new request *********** problem here ********* 
      Console.WriteLine("after req_mutex.WaitOne()"); 
      req_mutex.ReleaseMutex(); // release req mutex for more requests 

      Console.ReadLine(); 
     } 
    } 
} 

更多對於這一說法的證據:在父調用ReleaseMutex兩次會使事情第一「單擊」運行(和崩潰第二次)。您可以通過在創建時未獲取鎖來解決此問題:

Mutex req_mutex = new Mutex(false, "req_mutex");