19

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

互斥锁是这样创建的:

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();    
    }

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

有人可以澄清吗?

4

1 回答 1

30

根据 MSDN,AbandonedMutexException是:

当一个线程获取另一个线程通过退出而不释放它而放弃的 Mutex 对象时引发的异常。

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

然而,大多数时候 AbandonedMutexException 被引发,受互斥锁保护的数据结构的完整性无法得到保证,这就是为什么在 .NET 框架的 2.0 版中引入了这个异常:

废弃的互斥锁表示严重的编程错误。当线程退出而不释放互斥体时,受互斥体保护的数据结构可能不会处于一致状态。在 .NET Framework 2.0 版之前,此类问题很难发现,因为如果由于放弃互斥体而导致等待完成,则不会引发异常。

于 2013-03-17T04:37:58.753 回答