我有一个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();
}
}
答案 0 :(得分:4)
为什么不使用Dispose pattern? Mutex
继承自WaitHandle
和WaitHandle
实施IDisposable
。如果您有一个创建并使用IDisposable
的类,那么它也应该实现IDisposable
并妥善处置。不要让GC为您处理互斥锁,请在using
块中手动执行此操作,或手动调用.Dispose()
。通过这种方式,您可以随时了解谁在做什么,何时做什么。
This post引用了一句很棒的话:
如果对象实现了IDisposable,那么你应该考虑如何清理对象。
实现IDisposable的对象通常这样做是因为它们持有应该确定地释放的实际资源。
这正是这里发生的事情。
此外,我发现您正在使用命名的互斥锁。命名互斥锁用于跨进程,并作为操作系统句柄进行管理。是否有其他人获得相同的互斥量并试图释放它?你需要一个名为互斥的原因吗?这些通常很难处理,因为如果进程死亡并且互斥锁没有得到优雅处理,你可以放弃互斥锁和各种其他奇怪的东西。