我有一段非常简单的代码,很少抛出“System.ApplicationException:对象同步方法是从未同步的代码块中调用的。”调用 ReleaseMutex ()时。
我从逻辑上分析了该方法的流程,只是无法理解这种情况的发生方式/原因。
据我了解,在这种情况下,互斥体的所有权得到保证:
readonly string mutexKey;
public Logger(string dbServer, string dbName)
{
this.mutexKey = ServiceManagerHelper.GetServiceName(dbServer, dbName);
}
private void Log(LogType type, string message, Exception ex)
{
using (var mutex = new Mutex(false, mutexKey))
{
bool acquiredMutex;
try
{
acquiredMutex = mutex.WaitOne(TimeSpan.FromSeconds(5));
}
catch (AbandonedMutexException)
{
acquiredMutex = true;
}
if (acquiredMutex)
{
try
{
// some application code here
}
finally
{
mutex.ReleaseMutex();
}
}
}
}
最佳答案
catch (AbandonedMutexException)
{
acquiredMutex = true;
}
这是代码中非常严重的错误。捕获AbandonedMutexException永远是不正确的,它是非常严重的不幸事故。另一个线程获取了互斥锁,但是在不调用ReleaseMutex()的情况下终止了。您无法恢复丢失的同步,并且互斥锁不再可用。
您确实很幸运,因为犯了一个错误并假设您无论如何都获得了互斥量。你没有现在,ReleaseMutex()调用将轰炸,并带有您引用的异常。
除了终止程序(明智的选择)或完全禁用日志记录之外,您无法从此灾难中恢复,因此互斥量将不再使用。通过删除catch子句来做出明智的选择。发现问题的真正根源是,崩溃了且未调用ReleaseMutex()的线程不在此问题的讨论范围之内,没有任何提示。您一直在忽略这个问题,而是通过捕获AME来解决它,您不能忽略它。