C#多线程之旅(7)——终止线程

先交代下背景,写《C#多线程之旅》这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很多问题。

原文地址:C#多线程之旅(7)——终止线程 (原创:博客园-Jackson0714)

C#多线程之旅目录:

C#多线程之旅(1)——介绍和基本概念

C#多线程之旅(2)——创建和开始线程

C#多线程之旅(3)——线程池

C#多线程之旅(4)——APM初探

C#多线程之旅(5)——同步机制介绍

C#多线程之旅(6)——详解多线程中的锁

C#多线程之旅(7)——终止线程

更多文章正在更新中,敬请期待......

一、什么时候用Thread.Abort();

当我们想要立即终止一个线程时,可以用调用Thread.Abort方法来终止线程。这个和协作式取消不一样。

终止当前线程时会在当前线程上引发ThreadAbortException 异常。ThreadAbortExcetion是一个可以被应用程序捕获的特殊异常,在catch 块中会自动重新抛出这个异常,除非在catch块中调用ResetAbort方法。ResetAbort方法可以取消掉终止的请求,而且可以防止catch中再次抛出的ThreadAbortException终止当前线程。未执行的Finally块会在线程终止前执行。

二、Thread.Abort的用法

例子:

名称 代码 计算限制的 操作 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方法来等待线程的完成或终止。

四、Catch块中抛出异常

应用程序将会被终止,Finally块不会被执行

五、Finally块中抛出异常

应用程序将会被终止

六、Abort调用的时间

(1)线程Start之前调用Abort

线程会在Start被调用时终止线程。

(2)线程Sleeping的时候调用Abort

线程被中断,然后终止线程

(3)线程Blocked的时候调用Abort

线程被中断,然后终止线程

(4)线程被挂起的时候调用Abort

Throw ThreadStartException 引发Abort的调用,然后AbortRequested 被加到正在被终止的线程的ThreadState属性

(5)一个托管线程正在执行非托管代码时调用Abort

ThreadAbortException不会被抛出直到线程返回托管代码。

(6)如果同时Abort两个线程,有可能一个线程会设置状态信息,而另外一个线程执行Abort的方法。然而,应用程序不会检测到这种情形。

作  者: Jackson0714 出  处:http://www.cnblogs.com/jackson0714/ 关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教! 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我 声援博主:您的鼓励是作者坚持原创和持续写作的最大动力!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

C# 中参数验证方式的演变

一般在写方法的时候,第一步就是进行参数验证,这也体现了编码者的细心和缜密,但是在很多时候这个过程很枯燥和乏味,比如在拿到一个API设计文档的时候,通常会规定类型...

14720
来自专栏函数式编程语言及工具

Akka(6): become/unbecome:运算行为切换

   通过一段时间的学习了解,加深了一些对Akka的认识,特别是对于Akka在实际编程中的用途方面。我的想法,或者我希望利用Akka来达到的目的是这样的:作为传...

31490
来自专栏文渊之博

sql 日期格式汇总

SQLserver中用convert函数转换日期格式2008-01-15 15:51SQLserver中用convert函数转换日期格式 SQL Server中...

21450
来自专栏Keegan小钢

Android项目重构之路:实现篇(一)

前两篇文章《Android项目重构之路:架构篇》和《Android项目重构之路:界面篇》已经讲了我的项目开始搭建时的架构设计和界面设计,这篇就讲讲具体怎么实现的...

14930
来自专栏张善友的专栏

在Linux和Windows平台上操作MemoryMappedFile(简称MMF)

操作系统很早就开始使用内存映射文件(Memory Mapped File)来作为进程间的共享存储区,这是一种非常高效的进程通讯手段。.NET 4.0新增加了一个...

22760
来自专栏安恒网络空间安全讲武堂

nox&amp;CSAW部分pwn题解

暑假的时候遇到了一群一起学习安全的小伙伴,在他们的诱劝下,开始接触国外的CTF比赛,作为最菜的pwn选手就试着先打两场比赛试试水,结果发现国外比赛真有意思哎嘿。

21630
来自专栏liulun

ASP.NET Core教程【三】实体字段属性、链接标签、并发数据异常、文件上传及读取

前文索引: ASP.NET Core教程【二】从保存数据看Razor Page的特有属性与服务端验证 ASP.NET Core教程【一】关于Razor Page...

31460
来自专栏高爽的专栏

Java线程(篇外篇):阻塞队列BlockingQueue

       好久没有写文章了,这段时间事情比较杂,工作也比较杂乱,上周日刚搬完家,从自建房搬到了楼房,提升了一层生活品质,哈哈!不过昨天晚上在公交车上钱包被偷...

23800
来自专栏向治洪

微信支付实例

1,导入微信的libs包libammsdk.jar; 2,测试时使用weixinDemo中的debug_keystore; 3,需要注意应用要通过审核,并且几个...

65950
来自专栏更流畅、简洁的软件开发方式

我的数据访问类(第二版)—— for .net2.0 (一)

asp.net2.0已经出来好久了,由于许多的原因一直没有使用,一个月前才开始使用VS2005写东西。 这一个月里又重新学习了一下基础知识,比如多态、接口了什么...

21790

扫码关注云+社区

领取腾讯云代金券