我第一次尝试使用互斥锁,并在程序的两个单独实例上执行以下代码
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
一旦第一个实例租用互斥锁,它就会在第二个等待语句崩溃时出现异常
The wait completed due to an abandoned mutex.
关于我为什么会遇到此异常以及如何阻止它的任何想法?
解决方案:我可能应该更清楚地阅读mdsn文档。感谢Andrew指出我正确的方向
您可以使用WaitHandle.WaitOne方法请求互斥锁的所有权。拥有互斥锁的线程可以在重复调用WaitOne时请求相同的互斥锁,而不会阻止其执行。但是,线程必须调用ReleaseMutex方法相同的次数才能释放互斥锁的所有权。 Mutex类强制执行线程标识,因此互斥锁只能由获取它的线程释放。
答案 0 :(得分:19)
你的问题是你持有Mutex两次,但只发布一次,因为你错误地安排了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();
}
答案 1 :(得分:-2)
我认为你的问题源于using (var mutex = new Mutex(false, "mySpecialMutex"))
行。当第一个线程终止时,它会处理互斥对象,我相信这可能会导致你得到的错误。
如果可能,最好将互斥锁声明为该方法之外的(静态)类变量。然后你会在开始你的线程之前手动实例化它并在它们完成后处理它。