The next class in our list,
Mutex, can be thought of as a more powerful version of
ManualResetEvent, it is derived from
WaitHandle. An advantage of
Monitor is that you can use the methods from
WaitHandle such as
WaitOne. A disadvantage is that is much slower, at about half as fast as
Mutex is very useful when you must control access to a resource that could be accessed through multiple processes, like a data file used by several applications you have created. To write to the file, the writing thread must have total access to the file throughout the operating system.
When you create a
Mutex, you can assign it a name. If the name exists anywhere in the operating system then that
Mutex object instance will be returned. This is the reason why
Mutex is slower, also. The system must be checked to see if the
Mutex already exists. If it doesn’t exist, a new one is created. When the last thread in the operating system that references the named
Mutex terminates, the
Mutex is destroyed. The following code example shows how to use a
Mutex to control access to a file.
Our first program:
Dim mutexFile As Mutex Private Sub btnSetMutex_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSetMutex.Click mutexFile = New Mutex(False, "Mutex Name") mutexFile.WaitOne() 'do some file manipulation here such as write to it 'For demonstration purposes we will release 'the mutex in another button click End Sub Private Sub btnRelease_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnRelease.Click mutexFile.ReleaseMutex() End Sub
Our Second Program
Private Sub btnAquireMutex_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) Handles btnAquireMutex.Click() Dim mutexFile As Mutex mutexFile = New Mutex(False, "Mutex Name") mutexFile.WaitOne() 'Wait until the file is open Console.WriteLine("Mutex was released from another process") 'Now I know that I have explicit access to the file 'I can write to it now. mutexFile.ReleaseMutex() End Sub
Let’s examine the first program. A
mutexFile is created. Internally to the operating system, we name the mutex “Mutex Name”. This is the name that will be used to resolve any other calls to the same mutex from any other application that we create. On a form we have two buttons. For demonstration purposes, one button will acquire a lock on the resource, in this case the file, using the
Mutex and the other button will release the lock. This simulates a long running process on the file. As with the other synchronization classes, you should make sure to call
RelaseMutex sometime after a lock is acquired or a block on the resource will occur.
The second program is very straightforward. We create a
Mutex object called
fileMutex making sure we have named it the same as in the first program, “Mutex Name”. If this is not done the
Mutex classes will refer to different mutexes in the operating system. Then
WaitOne is called without a timeout value. This will make the thread wait until the
Mutex has been released. When the release button is clicked in the first program, the second can continue running since it can now acquire access to the resource.
Mutex was released from another process is printed in the output window. You can also close the first program and the lock will be released. When a thread exits that has a
Mutex lock on a resource,
ReleaseMutex is automatically called for you.
In summary, remember that
Monitor should be used most of the time. It is faster than a
Mutex should only be used when you need to synchronize across multiple processes to gain access to a common resource among several programs that you have written. Even though
Mutex allows for the wait methods where
Monitor does not, the other
WaitHandle classes should be considered before
Mutex if you need the wait methods first.