Search code examples
c#thread-safetytask-parallel-librarymutex

Mutex.TryOpenExisting() is thread safe?


I use Mutex.TryOpenExisting(). I wanted to know is thread safe ?

public class MutexNamedSystemDemo
{
    private const string _mutexName = @"Global\{C7F2DE44-8927-4B01-B8E1-D8F158A483A8}";
    private static Mutex _mutex;
    private static bool _intiallyOwned = false;
    private static int _count = 0;
    /*public MutexNamedSystemDemo()
     {
         _mutex = new Mutex(_intiallyOwned, _mutexName);
     }*/
 
     public void Main()
     {
         if (Mutex.TryOpenExisting(_mutexName, out _mutex) == false)
             _mutex = new Mutex(_intiallyOwned, _mutexName);
     }
}

Sometimes when it is executed, it gets an error that _mutex is null. If it is threadsafe, why does this happen?


Solution

  • It seems like you want to check if the mutex with a given name exists, then if it does use it, otherwise create it.

    If this is the case, you don't need to call Mutex.TryOpenExisting at all.

    You simply need:

    _mutex = new Mutex(_intiallyOwned, _mutexName);
    

    This is because the documentation for the constructor Mutex(Boolean, String) states that:

    If a name is provided and a synchronization object of the requested type already exists in the namespace, the existing synchronization object is used.

    I.e. it guaratees the behavior you need.

    To answer your question regarding thread safety - yes, Mutex.TryOpenExisting itself is thread safe.
    From Mutex class documentation:

    This type is thread safe.

    It doesn't mean that calling Mutex.TryOpenExisting and then invoking the constructor is atomic as a whole, but as I explained above it is not needed.
    A final note: all this does not explain your null. Since you didn't mention an exception thrown by the constructor, I believe it is a result of other parts of your code which are not shown above.