我不明白爲什麼.NET互斥體不會在一個等待線程中拋出AbandonedMutexException
,或者在調用Mutex.Dispose()
時釋放互斥體。爲什麼命名.NET互斥體在處置時拋出AbandonedMutexException?
特別是,像這樣的代碼就會死鎖:
public static void testCall()
{
using (var mutex = new System.Threading.Mutex(false, "testname"))
{
mutex.WaitOne();
Console.WriteLine("second call");
}
}
public static void Main(string[] args)
{
var thread = new System.Threading.Thread(testCall);
using (var mutex = new System.Threading.Mutex(false, "testname"))
{
mutex.WaitOne();
Console.WriteLine("first call");
thread.Start();
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 5));
Console.WriteLine("sleep done");
}
thread.Join();
}
你要知道,我明白了AbandonedMutexException
通常來自底層的WIN32互斥鎖,並在本機代碼只會在情況下被觸發所屬的線程死亡 - 我我一直在編寫C/C++代碼,並且完全瞭解底層設計。我也知道,下面的代碼是一個簡單的解決辦法:
using (var mutex = new System.Threading.Mutex(false, "testname"))
{
mutex.WaitOne();
try
{
Console.WriteLine("first call");
thread.Start();
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 1));
Console.WriteLine("sleep done");
}
finally
{
mutex.ReleaseMutex();
}
}
我不明白的是背後的.NET互斥不會強迫釋放時,對象已經明確地佈置在佔用鎖的理由。這不會更符合.NET編程範例的其餘部分嗎?如果/當開發人員明確銷燬一個鎖定的互斥鎖時......只有將其標記爲已廢棄纔有意義。
我不同意。如果代碼沒有處理異常,則適當的行爲是拋出'AbandonedMutexException',因爲鎖定互斥鎖的代碼由於意外行爲(例外)而丟失了它。我同意,'ReleaseMutex()'既不明智又有點過分,但'AbandonedMutexException'是有道理的。 – 2012-04-13 22:08:22
但是如果線程沒有退出,那麼這個互斥就不會被放棄。 – 2012-04-13 23:12:21
不,不是在放棄的WIN32意義上..但是你不會在你的例子中說如果拋出一個異常並且沒有處理*和*這個互斥體被拋棄了,認爲這個互斥體被拋棄了嗎? 「 – 2012-04-13 23:16:06