ENTERPRISE

Programming .NET Components : Working with Threads (part 4) - Aborting a Thread

12/24/2013 8:35:37 PM

3. Aborting a Thread

The Thread class provides an Abort( ) method, which can forcefully try to terminate a .NET thread. Calling Abort( ) throws an exception of type ThreadAbortException in the thread being aborted. ThreadAbortException is a special kind of exception. Even if the thread method uses exception handling to catch exceptions, as in the following example code:

    public void MyThreadMethod(  )
{
try
{
while(<some condition>)
{
<Do some work>
}
}
catch
{
//Handle exceptions here
}
}

after the catch statement is executed, .NET re-throws the ThreadAbortException to terminate the thread. This is done so that non-structured attempts that ignore the abort by jumping to the beginning of the thread method simply don't work:

    //Code that doesn't work when ThreadAbortException is thrown
public void MyThreadMethod( )
{
Resurrection:
try
{

while(<some condition>)
{
<Do some work>
}
}
catch
{
goto Resurrection;
}
}

Using non-structured goto instructions is strongly discouraged in any case. Never use goto, except to fall through in a C# switch statement.


The Abort( ) method has two overloaded versions:

    public sealed class Thread
{
public void Abort( );
public void Abort(object stateInfo)
//Other methods and properties
}

One version allows the party that calls Abort( ) to provide a generic parameter of type object called stateInfo. stateInfo can convey application-specific information to the aborted thread, such as why it's being aborted. The aborted thread can access the stateInfo object via the ExceptionState public property of the ThreadAbortException class, if the thread is using exception handling.

Example 2 demonstrates using Abort( ) to terminate a thread. The example creates a new thread, whose thread method simply traces an incrementing integer to the Output window. The thread method uses exception handling, and it traces to the Output window the information passed to it using the stateInfo parameter of Abort( ). Note that the thread that called Abort( ) uses Join( ) to wait for the thread to die. This is the recommended practice, because the thread can perform an open-ended number of operations in its catch and finally exception-handling statements.

Example 2. Terminating a thread using Abort( )
public class MyClass
{
public void DoWork( )
{
try
{
int i = 0;
while(true)
{
Trace.WriteLine(i++);
}

}
catch(ThreadAbortException exception)
{
string cause;
cause = (string)exception.ExceptionState;
Trace.WriteLine(cause);
}
}
}
MyClass obj = new MyClass( );
Thread workerThread = new Thread(obj.DoWork);
workerThread.Start( );

/* Do some work, then: */

workerThread.Abort("Time to go");
workerThread.Join( );


If Abort( ) is called before the thread is started, .NET doesn't start the thread when Thread.Start( ) is called. If Thread.Abort( ) is called while the thread is blocked (either by calling Sleep( ) or Join( ), or if the thread is waiting on one of the .NET synchronization objects), .NET unblocks the thread and throws a ThreadAbortException in it. However, you can't call Abort( ) on a suspended thread. Doing so results in an exception of type ThreadStateException on the calling side, with the error message "Thread is suspended; attempting to abort." .NET then terminates the suspended thread without letting it handle the exception.

The Thread class also has an interesting counter-abort method—the static ResetAbort( ) method:

    public static void ResetAbort(  );

Calling Thread.ResetAbort( ) in a catch statement prevents .NET from re-throwing a ThreadAbortException at the end of the catch statement:

    catch(ThreadAbortException exception)
{
Trace.WriteLine("Refusing to die");
Thread.ResetAbort( );
//Do more processing or even goto somewhere
}

ResetAbort( ) requires the ControlThread security permission.


Terminating a thread by calling Abort( ) isn't recommended, for a number of reasons. The first is that it forces the thread to perform an ungraceful exit. Often, the thread needs to release resources it holds and perform some sort of cleanup before terminating. You can, of course, handle exceptions and put the cleanup code in the finally method, but you typically want to handle unexpected errors that way and not use it as the standard way to terminate a thread. Second, nothing prevents the thread from abusing .NET and either performing as many operations as it likes in the catch statement, jumping to a label, or calling ResetAbort( ). If you want to terminate a thread, you should do so in a structured manner, using the .NET synchronization objects. You should signal the thread method to exit by using a member variable or event.

Calling Thread.Abort( ) has another liability: if the thread makes an interop call (using COM interop or P-Invoke), the interop call may take a while to complete. If Thread.Abort( ) is called during the interop call, .NET doesn't abort the thread; it lets the thread complete the interop call, only to abort it when it returns. This is another reason why Thread.Abort( ) isn't guaranteed to succeed (or succeed immediately).

Other  
  •  System Center Configuration Manager 2007 : Integrating Virtual Applications (part 3) - Creating Adobe Reader as a Virtual Application in ConfigMgr R2
  •  System Center Configuration Manager 2007 : Integrating Virtual Applications (part 2) - Activating Application Virtualization in ConfigMgr 2007 R2
  •  System Center Configuration Manager 2007 : Integrating Virtual Applications (part 1) - What Is SoftGrid?
  •  Microsoft Lync Server 2010 : Planning for Internal Non-Voice Deployment - Planning for Archiving (part 2)
  •  Microsoft Lync Server 2010 : Planning for Internal Non-Voice Deployment - Planning for Archiving (part 1)
  •  Microsoft Lync Server 2010 : Planning for Internal Non-Voice Deployment - Planning for Conferencing
  •  Microsoft Lync Server 2010 : Planning for Internal Non-Voice Deployment - Planning for IM
  •  Microsoft Lync Server 2010 : Planning for Internal Non-Voice Deployment - Planning for Capacity
  •  Microsoft Lync Server 2010 : Planning for Internal Non-Voice Deployment - Determining Your Infrastructure Needs
  •  Microsoft Lync Server 2010 : Determining the Scope of the Deployment
  •  
    Top 10
    Review : Sigma 24mm f/1.4 DG HSM Art
    Review : Canon EF11-24mm f/4L USM
    Review : Creative Sound Blaster Roar 2
    Review : Philips Fidelio M2L
    Review : Alienware 17 - Dell's Alienware laptops
    Review Smartwatch : Wellograph
    Review : Xiaomi Redmi 2
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    VIDEO TUTORIAL
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8