被遗弃的互斥异常

nig*_*457 13 c# multithreading mutex multiprocessing abandonedmutexexception

我试图第一次使用互斥锁,并在程序的两个单独的实例上执行以下代码

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();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我运行它时,其中一个实例(我先运行的那个)打印出来

I got the mutex
sleeping
awaking and releasing mutex
Run Code Online (Sandbox Code Playgroud)

另一个实例打印

First check - some one locked the mutex
Run Code Online (Sandbox Code Playgroud)

一旦第一个实例租用互斥锁,它就会在第二个等待语句崩溃时出现异常

The wait completed due to an abandoned mutex.
Run Code Online (Sandbox Code Playgroud)

关于为什么我得到这个例外以及我如何能够阻止它的任何想法?

解决方案:我可能应该更清楚地阅读mdsn文档.谢谢安德鲁指出我正确的方向

您可以使用WaitHandle.WaitOne方法请求互斥锁的所有权.拥有互斥锁的线程可以在重复调用WaitOne时请求相同的互斥锁,而不会阻止其执行.但是,线程必须调用ReleaseMutex方法相同的次数才能释放互斥锁的所有权.Mutex类强制执行线程标识,因此互斥锁只能由获取它的线程释放.

And*_*ber 19

你的问题是你持有Mutex两次,但只发布一次,因为你的if陈述错误排列.你的第一次执行会捕获它两次 - 在这两个if语句中,但你的代码只发布一次.

您需要重新组织ifs,以便只捕获互斥锁一次.

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();
}
Run Code Online (Sandbox Code Playgroud)