AbandonedMutexException:由于放弃了互斥锁而导致等待完成

时间:2015-12-31 02:15:19

标签: c# .net .net-2.0

为什么以下结构会导致AbandonedMutexException。即使有错误或方法返回。互斥体正在被释放。

static Mutex WriteMutex = new Mutex(false, @"Global\mutex2203");

public static void Demo()
{

    try
    {
        WriteMutex.WaitOne();

        //rest of coding stuff here
    }
    finally
    {
            WriteMutex.ReleaseMutex();
    }

}

收到报告无法重新生成错误。

编辑:例外情况发生在WriteMutex.WaitOne();没有其他代码。只有这种方法才能触及互斥锁。

4 个答案:

答案 0 :(得分:6)

当一个线程获得另一个线程放弃的AbandonedMutexException对象时,抛出Mutex,而不释放它(参见AbandonedMutexException)。您在问题中引用的代码不一定是导致异常的代码,只是"接收"它(即检测抛出异常的情况)。

也就是说,另一个线程中的代码(可能是相同的方法但可能不是)获取Mutex但不释放它并允许其线程在没有Mutex被释放的情况下退出。然后运行上面显示的代码的线程在尝试获取Mutex时抛出异常。

答案 1 :(得分:1)

异常发生在哪里?当你WriteMutex.WaitOne();时会发生吗?

如果是这样,那么必须有一些东西(可能不在你发布的代码中)取得它的所有权,然后在你获得异常之前退出。

使用异步方法也可能是使用互斥锁的代码的问题,因为交换线程。确保您没有以不兼容的方式使用任何这些东西。

另外,请注意,命名的互斥体不是您的应用程序本地的:其他进程可能会与它混在一起(问题可能就在那里)。如果你想要一些本地的东西,不要给它起一个名字,或者甚至更好地使用一些更高效且更不容易出错的东西,就像这种情况下的lock关键字一样。

有关正确使用互斥锁(并避免出现类似问题)的一些不错的详细信息,请访问:What is a good pattern for using a Global Mutex in C#?

答案 2 :(得分:0)

对我来说,我得到的“等待已完成,原因是互斥被遗弃了”。警告,因为控制台应用程序正在任务计划程序下运行,并且任务计划程序正在终止它。那不是我想要的行为。

我通过以下方法解决了该问题:转到有问题的任务,编辑触发器,然后取消选中“如果任务的运行时间超过:则停止任务”选项。

请注意,还有其他一些选项也可能导致任务终止。

“条件”标签:电源->“如果计算机切换为电池电源,则停止”

“设置”标签:“如果任务的运行时间超过以下时间,则停止任务:”

答案 3 :(得分:0)

您还必须在WriteMutex.Dispose()块中调用finally,但最好使用using块。 尝试使用以下模式: https://stackoverflow.com/a/229567/2185689