GOTCHA 55 Abort() takes time to clean up


GOTCHA #55 Abort() takes time to clean up

As you saw in Gotcha #52, "ThreadAbortExceptiona hot potato," when you abort a THRead, the CLR throws a ThreadAbortException on it. The thread can do whatever cleanup it needs to by handling the exception. The CLR then executes all the finally blocks in the thread's call stack before actually terminating it. So there might be a delay between the time you call Abort() and the time the thread quits. This is illustrated in Example 7-7.

Example 7-7. Delay during Abort

C# (JoinAbort)

 using System; using System.Threading; namespace AbortAndJoin {     class Test     {         private static void Worker()         {             Console.WriteLine("Worker started");             try             {                 Thread.Sleep(5000);             }             finally             {                 Console.WriteLine("Worker enters finally {0}",                     DateTime.Now.ToLongTimeString());                 Thread.Sleep(10000);                 // Simulates some cleanup activity                 Console.WriteLine("Cleanup done in Worker {0}",                     DateTime.Now.ToLongTimeString());             }         }         [STAThread]         static void Main(string[] args)         {             Thread workerThread                 = new Thread(new ThreadStart(Worker));             workerThread.IsBackground = true;             workerThread.Start();             Thread.Sleep(1000);             Console.WriteLine("Aborting thread {0}",                 DateTime.Now.ToLongTimeString());             workerThread.Abort();             workerThread.Join();             Console.WriteLine("Thread has aborted {0}",                 DateTime.Now.ToLongTimeString());         }     } } 

VB.NET (JoinAbort)

 Imports System.Threading Module Test     Private Sub Worker()         Console.WriteLine("Worker started")         Try             Thread.Sleep(5000)         Finally             Console.WriteLine("Worker enters finally {0}", _                 DateTime.Now.ToLongTimeString())             Thread.Sleep(10000)             ' Simulates some cleanup activity             Console.WriteLine("Cleanup done in Worker {0}", _                 DateTime.Now.ToLongTimeString())         End Try     End Sub     Public Sub Main()         Dim workerThread As New Thread(AddressOf Worker)         workerThread.IsBackground = True         workerThread.Start()         Thread.Sleep(1000)         Console.WriteLine("Aborting thread {0}", _          DateTime.Now.ToLongTimeString())         workerThread.Abort()         workerThread.Join()         Console.WriteLine("Thread has aborted {0}", _          DateTime.Now.ToLongTimeString())     End Sub End Module 

In this example, the Worker() method's finally block introduces a delay to simulate some activity. Main() first starts a thread to run the Worker() method. After a delay, it invokes Abort() on that thread. Then it calls Join() to wait for cleanup and completion. The output is shown in Figure 7-8.

Figure 7-8. Output from Example 7-7


If your application requires you to Abort() a thread and perform some operation after that thread has quit, you should call Join() on the thread after calling Abort(). This waits for the thread to clean up properly and exit gracefully before you continue processing.

You may want to call the Join() method with a reasonable timeout to avoid any potential starvation or deadlock, as in:

     workerThread.Join(2000);  // Wait two seconds for                          // the thread to complete


IN A NUTSHELL

Ask yourself if you should call Join() after a call to Abort(). That is, ask if you need to wait for the thread to actually quit.

SEE ALSO

Gotcha #52, "ThreadAbortExceptiona hot potato" and Gotcha #54, "ResetAbort() may lead to surprises."



    .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