GOTCHA #51 Interrupt () kicks in only when a thread is blockedWhen you invoke the Interrupt() method on a thread, the CLR throws a THReadInterruptedException in the thread's context. However, this only happens when the thread is blockedfor instance, when it enters Sleep(), Join(), Wait(), or requests a lock. If the thread is busy executing, the exception is not received until the thread blocks. So if you call Interrupt() on a thread, the thread may not be interrupted for quite some time. Furthermore, there is no guarantee that the thread will be interrupted at all. The thread may catch the ThreadInterruptedException and just ignore it. Consider Example 7-3. Example 7-3. Interrupting a threadC# (Interrupt) using System; using System.Threading; namespace Interrupting { class Test { public static void Worker() { try { Console.WriteLine("worker started at {0}", DateTime.Now.ToLongTimeString()); string str = null; for(int i = 0; i < 30000; i++) { str += i.ToString(); // Simulating some activity } Thread.Sleep(1000); } catch(ThreadInterruptedException) { Console.WriteLine("Thread interrupted at {0}", DateTime.Now.ToLongTimeString()); } Console.WriteLine( "Continuing after Exception is caught"); } [STAThread] static void Main(string[] args) { Thread workerThread = new Thread( new ThreadStart(Worker)); //workerThread.IsBackground = true; workerThread.Start(); Thread.Sleep(1000); Console.WriteLine("Interrupting worker at {0}", DateTime.Now.ToLongTimeString()); workerThread.Interrupt(); } } } VB.NET (Interrupt) Imports System.Threading Module Test Public Sub Worker() Try Dim str As String = Nothing Console.WriteLine("worker started at {0}", _ DateTime.Now.ToLongTimeString()) For i As Integer = 0 To 30000 str += i.ToString() 'Simulating some activity Next Thread.Sleep(1000) Catch ex As ThreadInterruptedException Console.WriteLine("Thread interrupted at {0}", _ DateTime.Now.ToLongTimeString()) End Try Console.WriteLine( _ "Continuing after Exception is caught") End Sub Public Sub Main() Dim workerThread As New Thread(AddressOf Worker) 'workerThread.IsBackground = True workerThread.Start() Thread.Sleep(1000) Console.WriteLine("Interrupting worker at {0}", _ DateTime.Now.ToLongTimeString()) workerThread.Interrupt() End Sub End Module The Main() method creates a thread to execute the Worker() method. Worker() enters a busy computation cycle concatenating strings. Then Main() interrupts the thread. However, the THReadInterruptedException does not take effect until the thread finishes its computation and arrives at Sleep(). When you execute the program, you get the output shown in Figure 7-4. Figure 7-4. Output from Example 7-3As you can see, even though the thread is interrupted one second after it was started, it did not receive the ThreadInterruptedException until fourteen seconds later. IN A NUTSHELLRemember that a thread receives a ThreadInterruptedException only when it blocks, and that it is free to ignore the request. SEE ALSOGotcha #52, "ThreadAbortExceptiona hot potato" and Gotcha #54, "ResetAbort() may lead to surprises." |