13

我試圖用一個互斥體的第一次,並在下面的代碼的程序放棄的互斥體的異常

public void asynchronousCode() 
    { 
     using (var mutex = new Mutex(false, "mySpecialMutex")) 
     { 
      if (!mutex.WaitOne(1000, false)) 
      { 
       Console.WriteLine("First check - some one locked the mutex"); 
      } 

      if (!mutex.WaitOne(3000, false)) 
      { 
       Console.WriteLine("Second check- some one locked the mutex"); 
      } 
      else 
      { 
       Console.WriteLine("I got the mutex"); 
       Console.WriteLine("sleeping"); 
       Thread.Sleep(3000); 
       Console.WriteLine("Awaking and Releasing mutex"); 
       mutex.ReleaseMutex(); 
      } 
     } 
    } 

當我運行這一點,其中一個實例(一個我的兩個單獨實例執行第一次運行)打印

I got the mutex 
sleeping 
awaking and releasing mutex 

其他實例打印

First check - some one locked the mutex 

,並儘快爲第一研究所ANCE租賃互斥體,其在第二次等待語句崩潰,異常

The wait completed due to an abandoned mutex. 

爲什麼我收到此例外的任何想法和我是如何預防呢?

解決方案:我可能應該更清楚地閱讀mdsn文檔。感謝安德魯指點我在正確的方向

您可以使用WaitHandle.WaitOne方法來請求擁有一個互斥體。擁有互斥鎖的線程可以在重複調用WaitOne時請求相同的互斥量,而不會阻止其執行。但是,該線程必須調用ReleaseMutex方法的次數來釋放互斥量的所有權。互斥體類強制線程標識,因此互斥體只能由獲取它的線程釋放。

+2

您的第一次運行是持有互斥鎖兩次,但只釋放一次。因此它正在放棄它。 –

回答

19

由於您錯誤地安排了您的if聲明,您的問題是您持有互斥鎖兩次,但僅釋放一次。你的第一次執行在兩次得到 - 在這兩個if語句中,你的代碼只會釋放一次。

您需要重新組織if,因此您只需一次捕獲該互斥鎖。

bool captured = true; 
if (!mutex.WaitOne(1000, false)) 
{ 
     Console.WriteLine("First check - some one locked the mutex"); 
     captured = false; 
} 
if (!captured && !mutex.WaitOne(3000, false)) 
{ 
     Console.WriteLine("Second check- some one locked the mutex"); 
     captured = false; 
} 
if (captured) 
{ 
     Console.WriteLine("I got the mutex"); 
     Console.WriteLine("sleeping"); 
     Thread.Sleep(3000); 
     Console.WriteLine("Awaking and Releasing mutex"); 
     mutex.ReleaseMutex(); 
} 
-2

我認爲你的問題來自using (var mutex = new Mutex(false, "mySpecialMutex"))行。當第一個線程終止時,它會處理互斥對象,我相信這會導致你得到的錯誤。

如果可能,最好將該互斥體聲明爲該方法之外的(靜態)類變量。然後在開始線程之前手動實例化它,並在完成之後處理它。

+0

這是不正確的。被稱爲互斥體的系統範圍。這是沒有釋放它的處置,導致它有一個錯誤,而不是從來沒有釋放z雖然。 –

+0

我試着讓變量static並讓線程不終止,但我結束了相同的異常。 – nighthawk457