22.3 Aborting the Execution of a Thread

 <  Day Day Up  >  

You want to abort a thread.


Technique

To abort a thread, you need a reference to the Thread object for the thread in question. You then simply call Thread.Abort() :

 
 WorkerClass worker = new WorkerClass("ProcessMe.txt"); ThreadStart workerThreadStart = new ThreadStart(worker.DoSomeWork); Thread workerThread = new Thread(workerThreadStart); workerThread.Start(); // later on. . . workerThread.Abort(); 

It can take a short time for the aborting thread to actually terminate execution. If other threads need to ensure the aborting thread has terminated before they resume execution, then they can call Thread.Join() , which simply blocks (that is to say, waits, consuming virtually no CPU time) until the thread in question stops. Thus, to abort a thread, and not carry on processing until the thread termination is complete, use the following:

 
 workerThread.Abort(); workerThread.Join(); 

It is perfectly acceptable for a thread to abort itself:

 
 Thread.CurrentThread.Abort(); 

However, in most cases, it is more usual for a thread to terminate execution by simply returning from its start method.

Comments

There are a number of reasons why you might want to abort a thread. One common reason is that the user clicked the Cancel button to cancel some lengthy task that was being carried out on a worker thread. Other reasons are that the task was simply taking too long or that some other condition arose which made it preferable to cancel the task.

Aborting a thread works under the hood by causing a ThreadAbortException to be thrown on the thread to be aborted. The code to throw this exception is actually injected into the code that the thread in question is running. If this thread is currently asleep or suspended , the CLR resumes it to handle the exception.

ThreadAbortException is a special exception supplied by the .NET Framework. It has the unique property that as soon as it is handled, it immediately rethrows itself. It causes all relevant catch and finally blocks that contain the current execution point to be executed, until the thread exits, which normally guarantees that appropriate cleanup is performed. As a result, aborting a thread is a relatively safe operation, something that was not possible with unmanaged code.

The time taken to abort a thread clearly depends on the code in any catch and finally blocks that must execute. Also, if the thread is currently executing unmanaged code, the CLR cannot inject the ThreadAbortException until it returns to managed code.

One consequence is that you can add your own code to take special action if a thread is aborted by adding suitable catch blocks:

 
 catch (ThreadAbortException ex) {        // code to be executed if thread is to be aborted goes here } 

It is even possible for the thread that decided on the abort to supply extra application-specific information to the aborted thread; for example, this information might contain details of the reason for the abort. To do this, you must use a different overload of Thread.Abort() , which accepts an object reference as a parameter. For example, to supply a string containing the reason for the abort, use the following:

 
 workerThread.Abort("User hit the Cancel button"); 

The supplied object reference is available to the aborting thread as the ExceptionState property of the thrown ThreadAbortException :

 
 catch (ThreadAbortException ex) {         if (ex.ExceptionState != null)                 Console.WriteLine("Reason for the exception was: " +                   ex.ExceptionState.ToString()); } 

There's one additional flexibility: The aborting thread can decide that it doesn't want to abort after all by calling the static Thread.ResetAbort() method. This normally happens inside a catch handler and prevents the ThreadAbortException from auto-rethrowing itself again. One example is if you want a thread to refuse abort requests because it has nearly finished its task:

 
 // assume that perCentCompleted is an int that is being used to measure // how near we are to completing our task. catch (ThreadAbortException ex) {         if (perCentCompleted > 95)                 Thread.ResetAbort(); } 

Note, however, that this technique cannot prevent the ThreadAbortException from being thrown initially ”it only prevents it from being rethrown ”so you still need to add code to recover the situation once the catch block executes if you want the thread to continue executing.

 <  Day Day Up  >  


Microsoft Visual C# .Net 2003
Microsoft Visual C *. NET 2003 development skills Daquan
ISBN: 7508427505
EAN: 2147483647
Year: 2003
Pages: 440

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