我不明白为什么.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