2

我有一个 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();
    }
}
4

1 回答 1

4

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

这篇文章有一个很好的引述,你应该牢记在心:

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

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

这正是这里发生的事情。

我还看到您正在使用命名互斥锁。命名互斥锁用于跨进程并作为操作系统句柄进行管理。是否有其他人获得相同的互斥锁并试图释放它?您需要命名互斥体是否有原因?这些通常很难处理,因为如果进程终止并且互斥锁没有得到妥善处理,您可能会丢弃互斥锁和各种其他奇怪的东西。

于 2012-09-22T01:00:27.917 回答