Sleeping, Aborting, Suspending, Resuming, and Joining Threads

Sleeping, Aborting, Suspending, Resuming, and Joining Threads

Besides the Start method, threads also have other methods that let you control their behavior:

  • Sleep Makes a thread stop executing for a specified number of milliseconds .

  • Abort Aborts a thread.

  • Suspend Suspends a thread until you call Resume .

  • Resume Resumes a suspended thread's execution.

  • Join Returns only when the thread it's called on terminates.

We'll put these methods to work in a new example, ch15_02.cs. In this case, we'll have three threads, which will display "No Worries." , "No Problems." and "No Troubles." 20 times each. After creating these threads, we name them with the Thread class's Name property, and start thread1 :

 
 Thread thread1 = new Thread(new ThreadStart(NoWorries)); Thread thread2 = new Thread(new ThreadStart(NoProblems)); Thread thread3 = new Thread(new ThreadStart(NoTroubles)); thread1.Name = "Thread 1"; thread2.Name = "Thread 2"; thread3.Name = "Thread 3"; thread1.Start();     .     .     . 

thread1 just displays "No Worries." 20 times. After starting thread2 (which types "No Problems." 20 times), however, we'll make the main thread sleep three milliseconds and then abort this thread:

 
 thread1.Start(); thread2.Start(); Thread.Sleep(3); thread2.Abort();     .     .     . 

Aborting a thread terminates its execution immediately. You can determine when a thread was aborted by catching a ThreadAbortException exception in the thread's code. Here's how that looks in the code for thread2 , where we'll show a message when the thread is aborted:

 
 public void NoProblems() {  try  {     for (int loopIndex =0; loopIndex < 20; loopIndex++)     {       System.Console.WriteLine("No Problems.");     }   }  catch (ThreadAbortException)   {   System.Console.WriteLine("Thread {0} was aborted.",   Thread.CurrentThread.Name);   }   finally   {   System.Console.WriteLine("Thread {0} is done.",   Thread.CurrentThread.Name);   }  } 

Note also the finally block in this code, which also appears in the code for thread1 and thread3 , and will type a message when each thread terminates.

CATCHING THREAD INTERRUPTIONS

Besides ThreadAbortException , you can also catch ThreadInterruptedException , which occurs when a thread is interrupted by another thread.


After starting and aborting thread2 in Main , we'll start thread3 , which types "No troubles." 20 times. We'll then suspend it, wait 10 milliseconds, and then resume that thread:

 
 thread3.Start(); thread3.Suspend(); Thread.Sleep(10); thread3.Resume(); 

To make sure all three threads have finished, we'll call their Join methods, as you see in ch15_02.cs, Listing 15.2. A thread's Join method won't return until the thread is done executing (at which point its stream of execution "joins" the main thread again).

Listing 15.2 Suspending and Working with Two Threads (ch15_02.cs)
 using System.Threading; class ch15_02 {   static void Main()   {     ch15_02 app = new ch15_02();     app.StartThreads();   }   public void StartThreads()   {     Thread thread1 = new Thread(new ThreadStart(NoWorries));     Thread thread2 = new Thread(new ThreadStart(NoProblems));     Thread thread3 = new Thread(new ThreadStart(NoTroubles));     thread1.Name = "Thread 1";     thread2.Name = "Thread 2";     thread3.Name = "Thread 3";     thread1.Start();     thread2.Start();     Thread.Sleep(3);     thread2.Abort();     thread3.Start();     thread3.Suspend();     Thread.Sleep(10);     thread3.Resume();  thread1.Join();   thread2.Join();   thread3.Join();  System.Console.WriteLine("All threads finished.");   }   public void NoWorries()   {     Thread.Sleep(10);     try     {       for (int loopIndex =0; loopIndex < 15; loopIndex++)       {         System.Console.WriteLine("No Worries.");       }     }     catch (ThreadAbortException)     {       System.Console.WriteLine("{0} was aborted.",         Thread.CurrentThread.Name);     }     finally     {       System.Console.WriteLine("{0} is done.",         Thread.CurrentThread.Name);     }   }   public void NoProblems()   {     try     {       for (int loopIndex =0; loopIndex < 20; loopIndex++)       {          System.Console.WriteLine("No Problems.");       }     }     catch (ThreadAbortException)     {       System.Console.WriteLine("{0} was aborted.",         Thread.CurrentThread.Name);     }     finally     {       System.Console.WriteLine("{0} is done.",         Thread.CurrentThread.Name);     }   }   public void NoTroubles()   {     try     {       for (int loopIndex =0; loopIndex < 15; loopIndex++)       {          System.Console.WriteLine("No Troubles.");       }     }     catch (ThreadAbortException)     {       System.Console.WriteLine("{0} was aborted.",         Thread.CurrentThread.Name);     }     finally     {       System.Console.WriteLine("{0} is done.",         Thread.CurrentThread.Name);     }   } } 

Here are the results you see when you run ch15_02.cs. Note that thread2 was aborted as we requested , that thread1 finishes before the suspended thread3 , that all threads report when they're done, and the program only finishes when all three threads are done. (Also note that your results will depend on how your machine's scheduler is working and how big the resulting time slices are. You might have to adjust the time the code sleeps to see thread2 aborted, for example.)

 
 C:\>ch15_02 No Problems. No Problems. No Problems. Thread 2 was aborted. Thread 2 is done. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. No Worries. Thread 1 is done. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. No Troubles. Thread 3 is done. All threads finished. 

BACKGROUND THREADS

You can also set a thread's IsBackground property to true , making it a background thread. Background threads are the same as foreground threads, except that an application doesn't need to wait for background threads to terminate before finishing.


Now that we have multiple threads executing in the same program, there's a possibility that they might interfere with each other if they both work with the same object. The way out of that is to synchronize your threads.



Microsoft Visual C#. NET 2003 Kick Start
Microsoft Visual C#.NET 2003 Kick Start
ISBN: 0672325470
EAN: 2147483647
Year: 2002
Pages: 181

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