Object synchronization method was called from an unsynchronized block of code

荒凉一梦 提交于 2019-12-24 17:26:27

问题


I receive an exception in production with message "Object synchronization method was called from an unsynchronized block of code" on Mutex.ReleaseMutex() in following code:

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

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

There may be saveral processes which can use mutexes with different and same mutextName. And still I am not sure how that exception can happen there.


回答1:


This code:

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

That is not thread safe, more than one Mutex may get created. Using pretend time, let's look at this example:

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!

Hopefully that illustration isn't garbage.

Using the System.Lazy<T> class is a thread-safe way of doing lazy initialization, if you really want to do that with your mutex.

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

Given that, why are you trying to lazy initialize your Mutex? How are you disposing of it?



来源:https://stackoverflow.com/questions/7605077/object-synchronization-method-was-called-from-an-unsynchronized-block-of-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!