为什么以下结构会导致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();
没有其他代码。只有这种方法才能触及互斥锁。
答案 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