Why doesn't Mutex get released when disposed?

后端 未结 9 1080
青春惊慌失措
青春惊慌失措 2020-11-29 02:22

I have the following code:

using (Mutex mut = new Mutex(false, MUTEX_NAME))
{
    if (mut.WaitOne(new TimeSpan(0, 0, 30)))
    {
       // Some code that dea         


        
相关标签:
9条回答
  • 2020-11-29 02:57

    One of the primary uses of a mutex is to ensure that the only code which will ever see a shared object in a state which doesn't satisfy its invariants is the code which (hopefully temporarily) put the object into that state. A normal pattern for code which needs to modify an object is:

    1. Acquire mutex
    2. Make changes to object which cause its state to become invalid
    3. Make changes to object which cause its state to become valid again
    4. Release mutex

    If something goes wrong in after #2 has begun and before #3 has finished, the object may be left in a state which does not satisfy its invariants. Since the proper pattern is to release a mutex before disposing it, the fact that code disposes a mutex without releasing it implies that something went wrong somewhere. As such, it may not be safe for code to enter the mutex (since it hasn't been released), but there's no reason to wait for the mutex to be released (since--having been disposed--it never will be). Thus, the proper course of action is to throw an exception.

    A pattern which is somewhat nicer than the one implemented by the .NET mutex object is to have the "acquire" method return an IDisposable object which encapsulates not the mutex, but rather a particular acquisition thereof. Disposing that object will then release the mutex. Code can then look something like:

    using(acq = myMutex.Acquire())
    {
       ... stuff that examines but doesn't modify the guarded resource
       acq.EnterDanger();
       ... actions which might invalidate the guarded resource
       ... actions which make it valid again
       acq.LeaveDanger();
       ... possibly more stuff that examines but doesn't modify the resource
    }
    

    If the inner code fails between EnterDanger and LeaveDanger, then the acquisition object should invalidate the mutex by calling Dispose on it, since the guarded resource may be in a corrupted state. If the inner code fails elsewhere, the mutex should be released since the guarded resource is in a valid state, and the code within the using block won't need to access it anymore. I don't have any particular recommendations of libraries implementing that pattern, but it isn't particularly difficult to implement as a wrapper around other kinds of mutex.

    0 讨论(0)
  • 2020-11-29 02:57

    Dispose depends on WaitHandle to be released. So, even though using calls Dispose, it won't go into affect until the the conditions of stable state are met. When you call ReleaseMutex you're telling the system that you're releasing the resource, and thus, it is free to dispose of it.

    0 讨论(0)
  • 2020-11-29 03:06

    We need to understand more then .net to know what is going on the start of the MSDN page gives the first hint that someone “odd” is going on:

    A synchronization primitive that can also be used for interprocess synchronization.

    A Mutex is a Win32Named Object”, each process locks it by name, the .net object is just a wrapper round the Win32 calls. The Muxtex itself lives within the Windows Kernal address space, not your application address space.

    In most cases you are better off using a Monitor, if you are only trying to synchronizes access to objects within a single process.

    0 讨论(0)
提交回复
热议问题