使用互斥锁同步 C# 对象:"Object synchronization method was called from an unsynchronized block of code"错误



我有一个C#应用程序代码,在创建对象的过程中,我使用互斥体来同步一些代码。对象构造函数获取互斥对象,并仅在不再需要该对象时(在应用程序关闭期间)释放它。因此,释放互斥锁的一个地方是在对象析构函数中。出现的问题是,有时在对象析构函数中调用ReleaseMutex()时会出现异常。异常为:"对象同步方法是从未同步的代码块调用的"。看起来,执行gabage集合(有时调用对象析构函数)的线程与首先等待互斥(mutex.WaitOne(false,namedMutex))的线程不同。如何同步获取和释放同一线程上的互斥体以避免此异常?谢谢你的帮助!

public class MyObject
{
static ExtDeviceDriver devDrv;
private Mutex mut = new Mutex(false,myMutex);
public MyObject()
{
mut.WaitOne();
//Thread safe code here.
devDrv = new ExtDeviceDriver();
}
~MyObject()
{
mut.ReleaseMutex();
}
}

为什么不使用Dispose模式?Mutex继承自WaitHandleWaitHandle实现IDisposable。如果您有一个创建并使用IDisposable的类,那么它也应该实现IDisposable并正确地处理掉。不要让GC为你处理互斥,在using块中手动处理,或者在它上手动调用.Dispose()。这样你就可以随时知道谁在做什么以及什么时候做。

这篇文章有一句很棒的名言,你应该牢记在心:

如果对象实现IDisposable,那么您应该考虑如何清理对象。

实现IDisposable的对象通常会这样做,因为它们持有应该确定释放的实际资源。

这正是这里发生的事情。

我还看到您正在使用一个命名的互斥体。命名互斥对象跨进程使用,并作为操作系统句柄进行管理。是否有其他人正在获取相同的互斥并试图释放它?你需要一个命名的互斥体是有原因的吗?这些通常很难处理,因为如果进程死亡,并且互斥对象没有得到妥善处理,那么可能会有多余的互斥对象和其他各种奇怪的东西。

相关内容

最新更新