4.6 Control the Execution of a Thread


Problem

You need to control when a thread starts and stops and be able to pause the execution of a thread.

Solution

Use the Abort , Interrupt , Resume , Start , and Suspend methods of the Thread you need to control.

Discussion

The methods of the Thread class summarized in Table 4.1 provide a high degree of control over the execution of a thread. Each of these methods returns to the calling thread immediately. However, the current thread state plays an important role in the result of the method call, and the state of a thread can change rapidly . As a result, you must code defensively to catch and handle the different exceptions that can be thrown when you try to control the execution of a Thread .

Table 4.1: Controlling the Execution of a Thread

Method

Description

Abort

Terminates a thread by throwing a System.Threading.ThreadAbortException in the code that the thread is running. The aborted thread's code can catch the ThreadAbortException to perform cleanup, but the runtime will automatically throw the exception again to ensure that the thread terminates, unless ResetAbort is called. Abort returns immediately, but the runtime determines exactly when the exception is thrown, so you can't assume the thread has terminated by Abort returns. You should use the techniques described in recipe 4.7 if you need to determine when the aborted thread is actually finished. Once you abort a thread, you can't restart it.

Interrupt

Throws a System.Threading.ThreadInterruptedException in the code that the thread is running as long as the thread is currently in a WaitSleepJoin state. This means that the thread has called Sleep , Join (recipe 4.7) or is waiting to be signaled by a WaitHandle or acquire an object used for thread synchronization (recipe 4.8). If the thread is not in the WaitSleepJoin state, ThreadInterruptedException is thrown the next time the thread does enter the WaitSleepJoin state.

Resume

Resumes the execution of a suspended thread. (See the Suspend method.) Calling Resume on a thread that isn't suspended generates a System.Threading.ThreadStateException in the calling thread.

Start

Starts the execution of a new thread; see recipe 4.5 for a description of how to use the Start method.

Suspend

Suspends the execution of a thread until the Resume method is called. Suspending an already suspended thread has no effect, but calling Suspend on a thread that hasn't started or is already finished will generate a ThreadStateException in the calling thread.

The ThreadControlExample class shown here demonstrates the use of the Thread methods listed in Table 4.1. The example starts a second thread that periodically displays a message to the console and then goes to sleep. By entering commands at the command prompt, you can interrupt, suspend, resume, and abort the secondary thread.

 using System; using System.Threading; public class ThreadControlExample {     private static void DisplayMessage() {         // Repeatedly display a message to the console.         while (true) {             try {                 Console.WriteLine("{0} : Second thread running. Enter"                     + " (S)uspend, (R)esume, (I)nterrupt, or (E)xit.",                     DateTime.Now.ToString("HH:mm:ss.ffff"));                 // Sleep for 2 seconds.                 Thread.Sleep(2000);             } catch (ThreadInterruptedException) {                 // Thread has been interrupted. Catching the                  // ThreadInterruptedException allows the example to                  // take appropriate action and continue execution.                 Console.WriteLine("{0} : Second thread interrupted.",                     DateTime.Now.ToString("HH:mm:ss.ffff"));             } catch (ThreadAbortException abortEx) {                 // The object in the ThreadAbortException.ExceptionState                 // property is provided by the thread that called                  // Thread.Abort. In this case it contains a string that                  // describes the reason for the abort.                 Console.WriteLine("{0} : Second thread aborted ({1})",                       DateTime.Now.ToString("HH:mm:ss.ffff"),                     abortEx.ExceptionState);                 // Even though ThreadAbortException has been handled, the                 // runtime will throw it again to ensure the thread                  // terminates.             }         }     }     public static void Main() {         // Create a new Thread object and pass it a ThreadStart         // delegate instance that references DisplayMessage.         Thread thread = new Thread(new ThreadStart(DisplayMessage));         Console.WriteLine("{0} : Starting second thread.",               DateTime.Now.ToString("HH:mm:ss.ffff"));         // Start the second thread.         thread.Start();         // Loop and process the command entered by the user.         char command = ' ';         do {             string input = Console.ReadLine();             if (input.Length > 0) command = input.ToUpper()[0];             else command = ' ';             switch (command) {                 case 'S':                     // Suspend the second thread.                     Console.WriteLine("{0} : Suspending second thread.",                         DateTime.Now.ToString("HH:mm:ss.ffff"));                     thread.Suspend();                     break;                 case 'R':                     // Resume the second thread.                     try {                          Console.WriteLine("{0} : Resuming second thread.",                             DateTime.Now.ToString("HH:mm:ss.ffff"));                         thread.Resume();                     } catch (ThreadStateException) {                         Console.WriteLine("{0} : Thread wasn't suspended.",                             DateTime.Now.ToString("HH:mm:ss.ffff"));                     }                     break;                 case 'I':                     // Interrupt the second thread.                     Console.WriteLine("{0} : Interrupting second thread.",                         DateTime.Now.ToString("HH:mm:ss.ffff"));                     thread.Interrupt();                     break;                 case 'E':                     // Abort the second thread and pass a state object to                     // the thread being aborted, in this case a message.                     Console.WriteLine("{0} : Aborting second thread.",                           DateTime.Now.ToString("HH:mm:ss.ffff"));                     thread.Abort("Terminating example.");                     // Wait for the second thread to terminate.                     thread.Join();                     break;             }         } while (command != 'E');         // Wait to continue.         Console.WriteLine("Main method complete. Press Enter.");         Console.ReadLine();     } } 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

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