I have several threads that acquire Mutexes and then terminate.
The mutexes are stored in a main repository, and are properly released when the program exists. However, when the thread that allocated a Mutex exists, the mutex gets released automatically, and subsequent acquire AbandonedMutexException (also according to the documentation).
How can I avoid this exception, and keep using a Mutex even after the allocating thread finished? Is there another, more appropriate synchronization construct in .Net that doesn't have this limitation.
Note - I am looking for a cross-process synch mechanism with similar semantics to Mutex.
Response to the question
AFAIK there exist no such Mutex class. The AbandonedMutexException is quite annoying but it represents a real situation that can occur for which there is no automatic solution.
When you have cross process, or even cross thread communication, you must deal with the fact that any one of the participating entities can be unexpected and suddenly terminated for any number of reasons. Mutex's exist to protect resources, if a thread is abandoned while it holds a Mutex there is no way for the OS to guarantee that it left data in any consistent manner. This is very important because it means that the abandoning of the thread could have invalidated certain invariants being depended on by other threads.
The AbandonedMutexException is a way of proactively saying "bad things happened and you are now in an indeterminate state". There is really no other recoures for the operating system here.
Response to your answer
EventWaitHandle is different that Mutex and serves different purposes.
Mutex is used to protect a particular resource much like a lock statement. When a particular thread acquires a mutex it is said to own the Mutex. There can only be one owner at a time. So if all threads involved agree to only touch a resource when they have ownership of the Mutex, you can safely access a resource across thread.s
EventWaitHandle can be visualed, to a degree, as a thread safe event. It has the concept of signaled and unsignaled and any number of threads can wait for it to hit a signaled state. When it is signaled one of the waiting threads will be woken up and will start processing.
You can use an EventWaitHandle to implement a form of thread safety. Instead of lock ownership being the key to accessing the resource, being signaled from the event is the key to accessing the resource. However, the devil is once again in the details.
- Who is in charge of signaling the event? With a mutex, every thread is essentially screaming "me me me" and the OS picks one thread to win. With an EventWaitHandle you will be responsible for deciding when the next thread gets to go.
- What happens when someone kills a process via taskmgr? What if the process killed has a thread currently responding to an event on the EventWaitHandle?
2 but what happens when the item who gets to signal the wait handle next is taken down? You must account for this to avoid deadlock.
Looks like EventWaitHandle does what I want. It has a constructor that takes a name, so it's perfect for cross-process synch, and it doesn't have this problem.
There is nothing preventing you from using the Mutex after receiving an AbandonedMutexException
. From the doc:
The next thread to request ownership of the mutex can handle this
exception and proceed, provided that the integrity of the data
structures can be verified.
Of course, this assumes that you know what you (and your threads) are doing while they crash, and that basically means that the acquiring thread could just as well release the mutex before exiting.
So in the end your own solution of using EvenWaitHandle
is a better one than the mutex.