c# - 使用Mutex同步C#对象: "Object synchronization method was called from an unsynchronized block of code" error

标签 c# object synchronization mutex

我有一个 C# 应用程序代码,其中在创建对象期间使用互斥锁来同步某些代码。对象构造函数获取互斥体,并且仅在不再需要该对象时(在应用程序关闭期间)释放它。因此,释放互斥体的一个地方就是对象析构函数。出现的问题是,有时在对象析构函数中调用 ReleaseMutex() 时会出现异常。异常(exception)情况是:“从不同步的代码块调用对象同步方法”。看起来,执行 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 patternMutex 继承自 WaitHandle,并且 WaitHandle 实现 IDisposable。如果您有一个创建并使用 IDisposable 的类,它也应该实现 IDisposable 并正确处置。不要让 GC 为您处理互斥锁,请在 using block 中手动执行此操作,或者手动调用 .Dispose() 。这样您就可以随时知道谁在做什么、什么时候在做什么。

This post有一句话值得你牢记在心:

If the object implements IDisposable then you should think about how the object is getting cleaned up.

Objects that implement IDisposable usually do so because they are holding on to real resources that should be freed deterministically.

这正是这里发生的事情。

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

关于c# - 使用Mutex同步C#对象: "Object synchronization method was called from an unsynchronized block of code" error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12538977/

相关文章:

C++ 从主线程调用方法

c# - 找到旋转的差异,作为随时间统一的平均值 c#

javascript - 如何从对象数组中获取键和子键?

javascript - 这些代码的含义是什么? JavaScript

java - 将直到运行时才知道的对象转换为其类型

c - OpenCL CLK_LOCAL_MEM_FENCE 导致中止陷阱 6

java - 父子线程同步(子线程 "on monitor")

c# - MSTest ThrowsException 与异常对象的条件?

c# - Xamarin.Forms ListView 中的项目之间的填充

c# - 我使用信号量错了吗?