【问题标题】:Object synchronization method was called from an unsynchronized block of code从未同步的代码块调用对象同步方法
【发布时间】:2011-11-28 03:18:21
【问题描述】:

我在生产中收到异常消息“对象同步方法已从未同步的代码块中调用”在 Mutex.ReleaseMutex() 上的以下代码中:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}
[NonSerialized]
Mutex mutex;

public void Log(/*...*/)
{
    Mutex.WaitOne();
    try
    {
        /*...*/
    }
    finally
    {
        Mutex.ReleaseMutex();
    }
}

可能有一些特殊的进程可以使用具有不同和相同 mutextName 的互斥锁。 而且我仍然不确定该异常是如何在那里发生的。

【问题讨论】:

  • 实际上我怀疑这可能是因为 Mutex.WaitOne() 和 Mutex.ReleaseMutext() 中使用了不同的互斥量实例,因为单个进程中存在一些竞争条件,尽管有疑问。
  • 创建 Mutex 不是线程安全的 - 对于初学者。您最终可能会拥有多个互斥体。
  • 是的,Release 调用是针对额外的。

标签: c# .net synchronization


【解决方案1】:

这段代码:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}

这不是线程安全的,可能会创建多个 Mutex。使用假装时间,让我们看一下这个例子:

线程 A |线程 B ------------------------------------- 进入 一片空白? (是)进入 创建互斥量是否为空? (是)

希望那个插图不是垃圾。

使用System.Lazy<T> 类是一种执行延迟初始化的线程安全方式,如果您真的想用您的互斥锁来做到这一点。

private Lazy<Mutex> _lazyMutex = new Lazy<Mutex>(() => new Mutex(false, "MyMutex"));
Mutex Mutex
{
    get { return _lazyMutex.Value; }
}

鉴于此,您为什么要尝试延迟初始化 Mutex?你是怎么处理的?

【讨论】:

  • 在释放持有对象时释放Mutex。
猜你喜欢
  • 1970-01-01
  • 2012-09-14
  • 2015-02-06
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 2012-12-09
相关资源
最近更新 更多