先交代下背景,写《C#多线程之旅》这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很多问题。
当我们想要立即终止一个线程时,可以用调用Thread.Abort方法来终止线程。这个和协作式取消不一样。
终止当前线程时会在当前线程上引发ThreadAbortException 异常。ThreadAbortExcetion是一个可以被应用程序捕获的特殊异常,在catch 块中会自动重新抛出这个异常,除非在catch块中调用ResetAbort方法。ResetAbort方法可以取消掉终止的请求,而且可以防止catch中再次抛出的ThreadAbortException终止当前线程。未执行的Finally块会在线程终止前执行。
例子:
名称 代码 计算限制的 操作 public class ThreadWork { public static void DoWork() { try { for (int i = 0; i < 100; i++) { Tool.WriteMessage("Thread - working.", ConsoleColor.Green, ConsoleColor.White); Thread.Sleep(1000); } } catch (ThreadAbortException e) { Tool.WriteMessage("Thread - Caught ThreadAbortException - resetting.", ConsoleColor.Green, ConsoleColor.White); Tool.WriteMessage("Thread - Exception message: " + e.Message, ConsoleColor.Red, ConsoleColor.White); /*--如果调用Thread.ResetAbort()----- 1.取消终止线程的请求,并恢复线程,继续执行ResetAbort后面的语句,然后执行catch块之后的语句 2.若Catch块之后有Finally块,则执行Finally块,然后执行Finally块后面的语句。 */ /*----如果没有调用Thread.ResetAbort()---- 1.finally块在线程终止前执行,finally块之后的语句不会被执行,然后线程终止。 */ //Thread.ResetAbort(); //Tool.WriteMessage("Thread - ResetAbort", ConsoleColor.Green, ConsoleColor.White); } finally { Tool.WriteMessage("Thread - Finally blocks were executed.", ConsoleColor.Green, ConsoleColor.White); } Tool.WriteMessage("Thread - still alive and working.", ConsoleColor.Green, ConsoleColor.White); Thread.Sleep(1000); Tool.WriteMessage("Thread - finished working.", ConsoleColor.Green, ConsoleColor.White); } } 主程序 public class ThreadAbortTest { public static void Main() { try { ThreadStart myThreadDelegate = new ThreadStart(ThreadWork.DoWork); Thread myThread = new Thread(myThreadDelegate); myThread.Start();//启动线程myThread,执行DoWork方法 Thread.Sleep(100); Tool.WriteMessage("Main - aborting my thread.", ConsoleColor.Blue, ConsoleColor.White); myThread.Abort();//终止线程myThread myThread.Join();//等待线程myThread结束 Tool.WriteMessage("Main - ending.", ConsoleColor.White, ConsoleColor.White); } catch(Exception ex) { throw ex; } Console.ReadKey(); } } 工具类 public static class Tool { public static void WriteMessage(string message, ConsoleColor writeColor ,ConsoleColor backColor) { Console.ForegroundColor = writeColor; Console.WriteLine(message); Console.ForegroundColor = backColor; } } | 名称 | 代码 | 计算限制的 操作 | public class ThreadWork { public static void DoWork() { try { for (int i = 0; i < 100; i++) { Tool.WriteMessage("Thread - working.", ConsoleColor.Green, ConsoleColor.White); Thread.Sleep(1000); } } catch (ThreadAbortException e) { Tool.WriteMessage("Thread - Caught ThreadAbortException - resetting.", ConsoleColor.Green, ConsoleColor.White); Tool.WriteMessage("Thread - Exception message: " + e.Message, ConsoleColor.Red, ConsoleColor.White); /*--如果调用Thread.ResetAbort()----- 1.取消终止线程的请求,并恢复线程,继续执行ResetAbort后面的语句,然后执行catch块之后的语句 2.若Catch块之后有Finally块,则执行Finally块,然后执行Finally块后面的语句。 */ /*----如果没有调用Thread.ResetAbort()---- 1.finally块在线程终止前执行,finally块之后的语句不会被执行,然后线程终止。 */ //Thread.ResetAbort(); //Tool.WriteMessage("Thread - ResetAbort", ConsoleColor.Green, ConsoleColor.White); } finally { Tool.WriteMessage("Thread - Finally blocks were executed.", ConsoleColor.Green, ConsoleColor.White); } Tool.WriteMessage("Thread - still alive and working.", ConsoleColor.Green, ConsoleColor.White); Thread.Sleep(1000); Tool.WriteMessage("Thread - finished working.", ConsoleColor.Green, ConsoleColor.White); } } | 主程序 | public class ThreadAbortTest { public static void Main() { try { ThreadStart myThreadDelegate = new ThreadStart(ThreadWork.DoWork); Thread myThread = new Thread(myThreadDelegate); myThread.Start();//启动线程myThread,执行DoWork方法 Thread.Sleep(100); Tool.WriteMessage("Main - aborting my thread.", ConsoleColor.Blue, ConsoleColor.White); myThread.Abort();//终止线程myThread myThread.Join();//等待线程myThread结束 Tool.WriteMessage("Main - ending.", ConsoleColor.White, ConsoleColor.White); } catch(Exception ex) { throw ex; } Console.ReadKey(); } } | 工具类 | public static class Tool { public static void WriteMessage(string message, ConsoleColor writeColor ,ConsoleColor backColor) { Console.ForegroundColor = writeColor; Console.WriteLine(message); Console.ForegroundColor = backColor; } } |
---|---|---|---|---|---|---|---|---|
名称 | 代码 | |||||||
计算限制的 操作 | public class ThreadWork { public static void DoWork() { try { for (int i = 0; i < 100; i++) { Tool.WriteMessage("Thread - working.", ConsoleColor.Green, ConsoleColor.White); Thread.Sleep(1000); } } catch (ThreadAbortException e) { Tool.WriteMessage("Thread - Caught ThreadAbortException - resetting.", ConsoleColor.Green, ConsoleColor.White); Tool.WriteMessage("Thread - Exception message: " + e.Message, ConsoleColor.Red, ConsoleColor.White); /*--如果调用Thread.ResetAbort()----- 1.取消终止线程的请求,并恢复线程,继续执行ResetAbort后面的语句,然后执行catch块之后的语句 2.若Catch块之后有Finally块,则执行Finally块,然后执行Finally块后面的语句。 */ /*----如果没有调用Thread.ResetAbort()---- 1.finally块在线程终止前执行,finally块之后的语句不会被执行,然后线程终止。 */ //Thread.ResetAbort(); //Tool.WriteMessage("Thread - ResetAbort", ConsoleColor.Green, ConsoleColor.White); } finally { Tool.WriteMessage("Thread - Finally blocks were executed.", ConsoleColor.Green, ConsoleColor.White); } Tool.WriteMessage("Thread - still alive and working.", ConsoleColor.Green, ConsoleColor.White); Thread.Sleep(1000); Tool.WriteMessage("Thread - finished working.", ConsoleColor.Green, ConsoleColor.White); } } | |||||||
主程序 | public class ThreadAbortTest { public static void Main() { try { ThreadStart myThreadDelegate = new ThreadStart(ThreadWork.DoWork); Thread myThread = new Thread(myThreadDelegate); myThread.Start();//启动线程myThread,执行DoWork方法 Thread.Sleep(100); Tool.WriteMessage("Main - aborting my thread.", ConsoleColor.Blue, ConsoleColor.White); myThread.Abort();//终止线程myThread myThread.Join();//等待线程myThread结束 Tool.WriteMessage("Main - ending.", ConsoleColor.White, ConsoleColor.White); } catch(Exception ex) { throw ex; } Console.ReadKey(); } } | |||||||
工具类 | public static class Tool { public static void WriteMessage(string message, ConsoleColor writeColor ,ConsoleColor backColor) { Console.ForegroundColor = writeColor; Console.WriteLine(message); Console.ForegroundColor = backColor; } } | |||||||
(1)调用Thread.Abort()的输出结果: (2)未调用Thread.Abort()输出结果: (3)流程: (1)当主线程调用myThread.Abort()后,线程myThread抛出异常,线程myThread捕获到异常 (2)在myThread catch块中 如果调用Thread.ResetAbort()----- Step1.取消终止线程的请求,并恢复线程,继续执行ResetAbort后面的语句,然后执行catch块之后的语句 Step2.若catch块之后有Finally块,则执行执行Finally块,然后执行Finally块后面的语句。 如果没有调用Thread.ResetAbort()---- 1.finally块在线程终止前执行,finally块之后的语句不会被执行,然后线程终止。 |
当调用线程的Abort方法时,不能保证线程立即终止,有可能永远不能终止。这种情形发生在catch或finally块中存在长时间或无限的耗时操作时。
只有当catch或finally块中代码执行完才能终止线程。所以我们可以调用线程的Join方法来等待线程的完成或终止。
应用程序将会被终止,Finally块不会被执行
应用程序将会被终止
线程会在Start被调用时终止线程。
线程被中断,然后终止线程
线程被中断,然后终止线程
Throw ThreadStartException 引发Abort的调用,然后AbortRequested 被加到正在被终止的线程的ThreadState属性
ThreadAbortException不会被抛出直到线程返回托管代码。
作 者: Jackson0714 出 处:http://www.cnblogs.com/jackson0714/ 关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教! 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我 声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!