简体   繁体   中英

Use Mutex to synchronize C# object: “Object synchronization method was called from an unsynchronized block of code” error

I have a C# application code in which I use a mutex to synchronise some code during the creation of an object. The object constructor acquires the mutex and ONLY releases it when the object is no longer needed (during app shutdown). Thus one place to release the mutex would be in the object destructor. The problem that arose is that sometimes I got an exception during the call to ReleaseMutex() in the object destructor. The exception is: "Object synchronization method was called from an unsynchronized block of code". It appears that the thread that does gabage collection which calls the object destructor sometimes is not the same thread that waits for the mutex (Mutex.WaitOne(false, namedMutex)) in the first place. How do I syncrhonize the acquire and release of the mutex on the same thread to avert this exception? Thanks for your help!

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();
    }
}

Why don't you use the Dispose pattern ? Mutex inherits from WaitHandle and WaitHandle implements IDisposable . If you have a class that creates and uses an IDisposable it should also implement IDisposable and properly be disposed of. Don't let the GC dispose of your mutex for you, manually do it in a using block or manually call .Dispose() on it. This way you can always know who is doing what and when.

This post has a great quote that you should take to heart:

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.

Which is exactly what is happening here.

Also I see you are using a named mutex. Named mutexes are used across processes and are managed as operating system handles. Is anyone else acquiring the same mutex and trying to release it? Is there a reason you need a named mutex? These are usually tricky to deal with because you can have abandanded mutexes and all sorts of other weird stuff if the process dies and the mutex isn't gracefully handled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM