Coordinating Threads with the Mutex Class


Coordinating Threads with the Mutex Class

The .NET Compact Framework includes the Mutex class, which is a useful entity for coordinating threads. The Mutex class's name is derived from the term mutual exclusion. The class creates a region of code that can be executed by only one thread at a time.

A Mutex works by tracking which thread "holds" it. Only one thread may hold a Mutex at a time. If another thread tries to acquire it, then it blocks until the first thread releases its hold.

To use a Mutex to force only one thread to execute code at a time, follow these steps:

  1. Create an instance of the Mutex class. Pass false into the Mutex constructor so that the code that created the Mutex does not hold it.

  2. At the beginning of the code, place a call to Mutex.WaitOne() that may only be executed by one thread at a time.

  3. At the end of the code, place a call to Mutex.ReleaseMutex() that may only be executed by one thread at a time.

The following sample code demonstrates the steps:

 
 C# // Create instance of Mutex class.  The variable holding the // reference to this Mutex must be visible to the block of code // that will be protected. m_Mutex = new System.Threading.Mutex(false); // This is the code which we only want one thread at a time to execute // This call blocks until we acquire the Mutex m_Mutex.WaitOne(); // Put code here that only is executed by one thread at a time // Done, let others enter this code block now m_Mutex.ReleaseMutex(); VB ' Create instance of Mutex class.  The variable holding the ' reference to this Mutex must be visible to the block of code ' that will be protected. m_Mutex = new System.Threading.Mutex(False) ' This is the code which we only want one thread at a time to execute ' This call blocks until we acquire the Mutex m_Mutex.WaitOne() ' Put code here that only is executed by one thread at a time ' Done, let others enter this code block now m_Mutex.ReleaseMutex() 

There are some special considerations for using the Mutex :

  • Using Mutex objects is a cooperative activity. As the developer, you must structure your code so that any block of code that should be run by only a single thread at a time is protected with a Mutex .

  • You can use the same Mutex to protect two different regions of code. But this can cause unexpected behavior because of the following scenario. Thread 1 gets exclusive access to Code Block A through the Mutex . At the end of Code Block A, Thread 1 releases the Mutex . Soon after, Thread 1 gets to Code Block B and tries to acquire the same Mutex again, but Thread 2 has already acquired it in the meantime. If Thread 1 expected no one else to touch any of the code blocks between Code Block A and Code Block B, there could be unexpected failures.

  • The Monitor class is an alternative to the Mutex class. The Monitor class is very useful for making sure that only one thread has access to a specific data object at one time, while the Mutex class is well suited for protecting blocks of code. The Monitor class is described later in this chapter.

Suspending and Resuming Threads with Mutexes

The desktop .NET Framework includes support for the Thread.Suspend and Thread.Resume methods, which can force a thread to sleep indefinitely and then wake it back up. The .NET Compact Framework does not support these methods , so building applications with threads that can be suspended and resumed requires some thought and architecting. One way to simulate the Thread.Suspend and Thread.Resume methods is by using the Mutex class. The technique is especially useful on code running in a loop. To support suspending a thread that is running code in a loop, follow these steps:

  1. Create an instance of a Mutex object. Pass false to the constructor.

  2. At the top of the loop, call Mutex.WaitOne() .

  3. At the bottom of the loop, call Mutex.ReleaseMutex() .

  4. To suspend the thread, call Mutex.WaitOne() . This call blocks until the thread finishes the current iteration of its loop and releases the Mutex . The thread then blocks.

  5. To resume the thread, call Mutex.ReleaseMutex() .

The following code, derived from the SuspendAndTerminateThreads sample application, demonstrates how to suspend and resume a thread running a loop:

 
 C# // This code runs in a loop.  The thread can be suspended by calling // m_Mutex.WaitOne() while (!l_quit) {    m_Mutex.WaitOne();    // Insert useful code here    m_Mutex.ReleaseMutex(); } // This code runs on another thread, and will suspend the code above // This call blocks until the other thread finishes its loop // iteration, then that thread blocks m_Mutex.WaitOne(); // Other thread is now blocked ... // And now resume the other thread m_Mutex.ReleaseMutex(); VB ' This code runs in a loop.  The thread can be suspended by calling ' m_Mutex.WaitOne() while (l_quit = False)    m_Mutex.WaitOne()    ' Insert useful code here    m_Mutex.ReleaseMutex() End While ' This code runs on another thread, and will suspend the code above ' This call blocks until the other thread finishes its loop ' iteration, then that thread blocks m_Mutex.WaitOne() ' Other thread is now blocked ... ' And now resume the other thread m_Mutex.ReleaseMutex() 

Examining a Sample Application: SuspendAndTerminateThreads

This sample application has C# and VB versions in the folder \SampleApplications\Chapter4 . It demonstrates how to suspend and resume threads by using a Mutex and also how to set up a thread so that it can check to see if it should terminate.

The application has a button at the bottom labeled Start Threads. Clicking this button causes two threads to launch, one that counts by ones, and another by tens. Either of these threads can be independently suspended, resumed, or terminated by clicking the appropriately labeled button.



Microsoft.NET Compact Framework Kick Start
Microsoft .NET Compact Framework Kick Start
ISBN: 0672325705
EAN: 2147483647
Year: 2003
Pages: 206

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net