2
votes

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();
    }
}
1
What is your mutex protecting? What is the competition? For example, of you only release at app shutdown, can't you just do nothing and let the process termination release it?Marc Gravell
This is a case of using the wrong thing for the right reasons, or vice versa. I forget. In any case - sync objects need to be acquired and released on their own thread. Your usage of the object means that you can never guarantee that that will indeed occur. In other words - the thread that created your object (and thus, mutex), may be gone - it may have ceased to be, it is no more, bereft of life and resting in peace in the ThreadPool in the sky. If you are acquiring the Mutex so that the app will know it's already running, there's no reason to release it. Otherwise, please [cont'd]Shahar Prish
[cont'd] supply more information and maybe we can figure out what it is you are trying to do.Shahar Prish
Not sure what you're trying to accomplish here but your approach seems a bit suspect. Can you shed a little light on what you're trying to do?HasaniH

1 Answers

4
votes

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.