GOTCHA #53 Environment.Exit() brings down the CLRHow do you exit from a thread? You do that by returning from its associated method. There is an Environment.Exit() method, but it is somewhat more drastic: if you call the Exit() method you terminate the process, no matter which thread you call it from. None of the application's other threads gets a chance to clean up gracefully. Consider the code in Example 7-5. Example 7-5. Behavior of Exit()C# (KnowTheExit) using System; using System.Threading; namespace Exit { class Test { public static void Worker() { Console.WriteLine("worker thread started"); try { Thread.Sleep(5000); } catch(ThreadInterruptedException) { Console.WriteLine("worker interrupted"); } catch(ThreadAbortException) { Console.WriteLine("worker aborted"); } } [STAThread] static void Main(string[] args) { Thread workerThread1 = new Thread( new ThreadStart(Worker)); workerThread1.Start(); Thread.Sleep(1000); Console.WriteLine("Interrupting worker1 at {0}", DateTime.Now.ToLongTimeString()); workerThread1.Interrupt(); Thread workerThread2 = new Thread( new ThreadStart(Worker)); workerThread2.Start(); Thread.Sleep(1000); Console.WriteLine("Calling Exit"); Environment.Exit(0); } } } VB.NET (KnowTheExit) Imports System.Threading Module Test Public Sub Worker() Console.WriteLine("worker thread started") Try Thread.Sleep(5000) Catch ex As ThreadInterruptedException Console.WriteLine("worker interrupted") Catch ex As ThreadAbortException Console.WriteLine("worker aborted") End Try End Sub Public Sub Main() Dim workerThread1 As New Thread(AddressOf Worker) workerThread1.Start() Thread.Sleep(1000) Console.WriteLine("Interrupting worker1 at {0}", _ DateTime.Now.ToLongTimeString()) workerThread1.Interrupt() Dim workerThread2 As New Thread(AddressOf Worker) workerThread2.Start() Thread.Sleep(1000) Console.WriteLine("Calling Exit") Environment.Exit(0) End Sub End Module You first create a thread and interrupt it after a one-second delay. From the output shown in Figure 7-6, you can see that the thread does get interrupted. Then you create another thread and after a one-second delay you call Exit(). Note that the program terminates abruptly without giving the thread a chance to respond. The CLR terminates the process no matter which thread calls Exit(). This is undesirable. You might consider using Exit() in your application under special conditions, such as after dealing with an unhandled fatal exception. However, you need to exercise extreme caution in using Exit(). Figure 7-6. Output from Example 7-5IN A NUTSHELLThoroughly understand the consequence of calling Exit() on a threadyou are bringing down the entire process. SEE ALSOGotcha #49, "Foreground threads may prevent a program from terminating," Gotcha #50, "Background threads don't terminate gracefully," and Gotcha #58, "Threads from the thread pool are scarce." |