如何优雅地摆脱AbandonedMutexException?

时间:2013-03-17 02:50:50

标签: c# asp.net mutex abandonedmutexexception

我使用以下代码来同步多个正在运行的进程之间对共享资源的互斥访问。

互斥锁是这样创建的:

Mutex mtx = new Mutex(false, "MyNamedMutexName");

然后我使用此方法输入互斥部分:

public bool enterMutuallyExclusiveSection()
{
    //RETURN: 'true' if entered OK, 
    //         can continue with mutually exclusive section
    bool bRes;

    try
    {
        bRes = mtx.WaitOne();
    }
    catch (AbandonedMutexException)
    {
        //Abandoned mutex, how to handle it?

        //bRes = ?
    }
    catch
    {
        //Some other error
        bRes = false;
    }

    return bRes;
}

并将此代码留给它:

public bool leaveMutuallyExclusiveSection()
{
    //RETURN: = 'true' if no error
    bool bRes = true;

    try
    {
        mtx.ReleaseMutex();
    }
    catch
    {
        //Failed
        bRes = false;
    }

    return bRes;
}

但是,如果其中一个正在运行的进程崩溃,或者如果它从任务管理器终止,则互斥锁可能会返回AbandonedMutexException异常。所以我的问题是,摆脱它的优雅方式是什么?

这似乎工作正常:

    catch (AbandonedMutexException)
    {
        //Abandoned mutex
        mtx.ReleaseMutex();
        bRes = mtx.WaitOne();    
    }

但在这种情况下我可以进入相互排斥的部分吗?

有人可以澄清吗?

1 个答案:

答案 0 :(得分:24)

根据MSDN,AbandonedMutexException是:

  

一个线程获取Mutex对象时引发的异常   另一个线程已经放弃而没有释放它。

这意味着抛出此异常的线程是Mutex的新所有者(否则调用Mutex.ReleaseMutex Method就像你正在做的那样会触发ApplicationException),并且如果您可以确保受互斥锁保护的数据结构的完整性,您可以简单地忽略该异常并继续正常执行您的应用程序。

但是,大多数情况下都会引发AbandonedMutexException,因为无法保证受互斥锁保护的数据结构的完整性,这就是为什么在.NET框架的2.0版本中引入了这个异常的原因:

  

废弃的互斥锁表示严重的编程错误。当一个   线程退出而不释放互斥锁,即数据结构   受互斥锁保护的可能不是一致的状态。之前   .NET Framework 2.0版本很难发现这些问题   因为等待完成后没有抛出异常   一个废弃的互斥体。