GOTCHA 52 ThreadAbortExceptiona hot potato


GOTCHA #52 ThreadAbortExceptiona hot potato

When you call THRead.Abort() to abort a thread, the CLR throws a ThreadAbortException on it. This allows the thread to clean up its resources and terminate gracefully. Unlike the ThreadInterruptedException, the thread receives the ThreadAbortException instantaneously. This can be dangerous at times. If you are in the middle of a call, or doing some important processing, it does not wait for you to finish. Of course, you can handle the ThreadAbortException and stabilize your code. The ThreadAbortException, however, is a special kind of exception. When you leave the catch block, the CLR automatically throws it again, thus terminating the thread. Let's take a look at this in Example 7-4.

Example 7-4. Behavior of Thread.Abort()

C# (Abort)

 using System; using System.Threading; namespace ThreadAborting {     class Test     {         private static void Worker()         {             try             {                 try                 {                     Thread.Sleep(5000);                 }                 catch(ThreadAbortException)                 {                     Console.WriteLine(                         "ThreadAbortException caught");                 }                 Console.WriteLine(                     "Let's leave the method now");             }             finally             {                 Console.WriteLine("In the finally block");             }         }         [STAThread]         static void Main(string[] args)         {             Thread workerThread = new Thread(                 new ThreadStart(Worker));             workerThread.Start();             Thread.Sleep(1000);             Console.WriteLine("Calling abort");             workerThread.Abort();             Thread.Sleep(1000);             Console.WriteLine("Main done");         }     } } 

VB.NET (Abort)

 Imports System.Threading Module Test     Private Sub Worker()         Try             Try                 Thread.Sleep(5000)             Catch ex As ThreadAbortException                 Console.WriteLine("ThreadAbortException caught")             End Try             Console.WriteLine("Let's leave the method now")         Finally             Console.WriteLine("In the finally block")         End Try     End Sub     Public Sub Main()         Dim workerThread As New Thread(AddressOf Worker)         workerThread.Start()         Thread.Sleep(1000)         Console.WriteLine("Calling abort")         workerThread.Abort()         Thread.Sleep(1000)         Console.WriteLine("Main done")     End Sub End Module 

In this example, Main()starts a thread to run the Worker() method. Then it invokes Abort() on that thread. The thread receives the ThreadAbortException right away. The exception is caught in the catch block. Note that there is no throw within the catch block; however, the exception is re-thrown automatically. As a result, instead of the "Let's leave the method now" message, the "In the finally block" message gets printed, as shown in the output in Figure 7-5.

Figure 7-5. Output from Example 7-4


The ThreadAbortException is a hot potato. The CLR throws it automatically from the catch block in order to terminate the thread (Want to catch it again? No problem, it'll be re-thrown again). There is no guarantee that any statements in your method will be executed. However, all the finally blocks in the call stack are visited.

IN A NUTSHELL

Write code defensively with the expectation that the thread may be aborted. Understand the special nature of the ThreadAbortException.

SEE ALSO

Gotcha #51, "Interrupt () kicks in only when a thread is blocked," Gotcha #54, "ResetAbort() may lead to surprises," and Gotcha #55, "Abort() takes time to clean up."



    .NET Gotachas
    .NET Gotachas
    ISBN: N/A
    EAN: N/A
    Year: 2005
    Pages: 126

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