C# 从未同步的代码块调用了对象同步方法

C# 从未同步的代码块调用了对象同步方法,c#,.net,synchronization,C#,.net,Synchronization,我在生产中收到一个异常,在以下代码中的Mutex.ReleaseMutex()上显示消息“从未同步的代码块调用了对象同步方法”: Mutex Mutex { get { return mutex ?? (mutex = new Mutex(false, mutexName)); } } [NonSerialized] Mutex mutex; public void Log(/*...*/) { Mutex.WaitOne(); try { /*

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

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

public void Log(/*...*/)
{
    Mutex.WaitOne();
    try
    {
        /*...*/
    }
    finally
    {
        Mutex.ReleaseMutex();
    }
}
可能有一些saveral进程可以使用具有不同和相同mutextName的互斥体。 我仍然不确定这种异常是如何发生的。

以下代码:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}
这不是线程安全的,可能会创建多个互斥锁。使用假装时间,让我们看一下这个示例:

Thread A | Thread B ------------------------------------- Enters Is Null? (yes) Enters Create Mutex Is Null? (yes) <- Thread A hasn't assigned it yet. Assign mutex Create Mutex Use Mutex Assign mutex <- Oops! We just overwrote the mutex thread A created! Release Mutex <- Oops! We are trying to release the mutex Thread B created without owning it! 螺纹A |螺纹B ------------------------------------- 进入 是空的吗?(是)进入 创建互斥是空的吗?(是)新互斥锁(假,“MyMutex”); 互斥互斥 { 获取{return\u lazyMutex.Value;} } 既然如此,为什么要尝试惰性地初始化互斥体?您是如何处理它的?

此代码:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}
这不是线程安全的,可能会创建多个互斥锁。使用假装时间,让我们看一下这个示例:

Thread A | Thread B ------------------------------------- Enters Is Null? (yes) Enters Create Mutex Is Null? (yes) <- Thread A hasn't assigned it yet. Assign mutex Create Mutex Use Mutex Assign mutex <- Oops! We just overwrote the mutex thread A created! Release Mutex <- Oops! We are trying to release the mutex Thread B created without owning it! 螺纹A |螺纹B ------------------------------------- 进入 是空的吗?(是)进入 创建互斥是空的吗?(是)新互斥锁(假,“MyMutex”); 互斥互斥 { 获取{return\u lazyMutex.Value;} }
既然如此,为什么要尝试惰性地初始化互斥体?您是如何处理它的?

事实上,我怀疑这可能是因为mutex.WaitOne()和mutex.ReleaseMutext()中使用了不同的互斥实例,因为单个进程中存在一些竞争条件,尽管我对此表示怀疑。对于初学者来说,互斥体的创建不是线程安全的。你可能会有多个互斥体。是的,释放调用是在多个互斥体上进行的。事实上,我怀疑这可能是因为mutex.WaitOne()和mutex.ReleaseMutext()中使用了不同的互斥体实例,因为在单个进程中存在一些竞争条件,尽管我有疑问。互斥体的创建不是线程安全的——对于初学者来说。您可能最终拥有多个互斥体。是的,并且会对额外的互斥体进行释放调用。释放保留对象时会释放互斥体。释放保留对象时会释放互斥体。