大家都知道在C#里面,我们可以使用 Thread.Start方法来启动一个线程,当我们想停止执行的线程时可以使用Thread.Abort方法来强制停止正在执行的线程,但是请注意,你确定调用了Thread.Abort方法后线程就立刻停止了吗? 答案是:不是!

下面我们来解释一下Abort方法是如何工作的。因为公用语言运行时管理了所有的托管的线程,同样它能在每个线程内抛出异常。Abort方法能在目标线程中抛出一个ThreadAbortException异常从而导致目标线程的终止。不过Abort方法被调用后,目标线程可能并不是马上就终止了。因为只要目标线程正在调用非托管的代码而且还没有返回的话,该线程就不会立即终止。而如果目标线程在调用非托管的代码而且陷入了一个死循环的话,该目标线程就根本不会终止。不过这种情况只是一些特例,更多的情况是目标线程在调用托管的代码,一旦Abort被调用那么该线程就立即终止了。

其实一个线程在运行时,我们可以通过Thread.ThreadState属性读出它的状态,正在运行的线程状态就是ThreadState.Running。然后如果我们想强制停止正在执行的线程,就会调用Thread.Abort方法,但是Thread.Abort方法做的事情只是在线程上抛出了一个ThreadAbortException异常,然后将线程的状态置为ThreadState.AbortRequested,MSDN对AbortRequested状态的解释是:已对线程调用了 Thread.Abort 方法,但线程尚未收到试图终止它的挂起的System.Threading.ThreadAbortException,也就是说线程在ThreadState.AbortRequested状态时表示即将结束但是还没有真正结束。可是Thread.Abort方法将线程的状态置为ThreadState.AbortRequested后就立马返回了,而线程真正结束后的状态应该是ThreadState.Aborted,所以一定要注意在调用了Thread.Abort方法后,要记得循环检查Thread.ThreadState属性的值或者调用Thread.Join方法来确保被终止线程已经真正停止,只有当Thread.ThreadState属性为Aborted或Thread.Join方法返回时,才表示线程真正结束了。

下面我就写一个示例代码来说明在调用Thread.Abort方法后,怎样保证线程停止后代码才会继续执行

var thread = new Thread(
new ThreadStart(
() =>
{
while (true)
{
//该线程会进行无限循环,自己不会结束
Thread.Sleep();
}
})); thread.IsBackground = true;
thread.Start();//启动线程 thread.Abort();//调用Thread.Abort方法试图强制终止thread线程 //上面调用Thread.Abort方法后线程thread不一定马上就被终止了,所以我们在这里写了个循环来做检查,看线程thread是否已经真正停止。其实也可以在这里使用Thread.Join方法来等待线程thread终止,Thread.Join方法做的事情和我们在这里写的循环效果是一样的,都是阻塞主线程直到thread线程终止为止
while (thread.ThreadState!=ThreadState.Aborted)
{
//当调用Abort方法后,如果thread线程的状态不为Aborted,主线程就一直在这里做循环,直到thread线程的状态变为Aborted为止
Thread.Sleep();
} //当跳出上面的循环后就表示我们启动的线程thread已经完全终止了

不过请记住使用Thread.Abort方法来终止正在执行的线程并不是一个好的方法,因为Abort方法是通过在线程上抛异常来终止线程的,这样可能会产生一些意想不到的问题。最好的办法是在启动的线程中加信号灯,当想要终止线程执行时就更改信号灯的状态,启动的线程当读到信号灯状态改变后自己结束代码的执行,这才是最安全的做法。

原文链接:https://www.cnblogs.com/OpenCoder/p/4587249.html

C# Thread.Abort方法真的让线程停止了吗?的更多相关文章

  1. EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真

    EF Core使用SQL调用返回其他类型的查询   假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...

  2. 注意!你的Thread.Abort方法真的让线程停止了吗?

    大家都知道在C#里面,我们可以使用 Thread.Start方法来启动一个线程,当我们想停止执行的线程时可以使用Thread.Abort方法来强制停止正在执行的线程,但是请注意,你确定调用了Threa ...

  3. C# Thread.Abort方法与ThreadAbortException异常(取消线程与异常处理)

    1.Abort当前线程,后续程序不会执行 class Program { public static Thread thread1; static void Main(string[] args) { ...

  4. Thread.Abort 方法

    [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] public void Abort() 在调用此方 ...

  5. 04 Thread的方法(源代码) 和 线程的状态

      1 .Thread中重要的属性 publicclass Thread implements Runnable { //继承自Runnable接口private char name[]; // 以c ...

  6. Thread的中断机制(interrupt),循环线程停止的方法

    一.中断原理 中断线程 线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个 ...

  7. 线程的Abort方法有感

    今天看CSDN上一个很老的帖子,有个人说Thread.Abort()方法调用之后一定会抛出异常,我对这个有点疑问. 于是自己做了一个测试demo,来研究Abort抛出异常的时机.废话少说,直接上代码: ...

  8. Java线程 - sleep()和wait()方法的区别, 线程阻塞BLOCKED和等待WAITING的区别

    一. sleep()和wait()方法的区别 sleep()方法 sleep()方法是Thread类的方法,通过其定义可知是个native方法,在指定的时间内阻塞线程的执行.而且从其注释中可知,并不会 ...

  9. 注意Thread.interrupt()方法的真正作用并不是用来中断线程

      程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误.      在本篇文章中,我们针对这些难题之一:如何中断一个正在 ...

随机推荐

  1. FFmpeg4.0笔记:file2rtmp

    Github: https://github.com/gongluck/FFmpeg4.0-study.git #include <iostream> using namespace st ...

  2. 作业调度系统quartz.net

    任务调度在我们日常开发过程中非常常见,比如:每天晚上0点自动执行某某操作:每周三晚上2点执行某某操作:......当然,我们处理这类问题的方法也有很多,比如:sql的自动任务:windows上创建任务 ...

  3. 文本框仅可接收decimal

    文本框html如下: <div><label class="label">价格:</label><input id="TextP ...

  4. Java代码审计连载之—添油加醋

    在代码审计中,按业务流程审计当然是必须的,人工的流程审计的优点是能够更加全面的发现漏洞,但是缺点是查找漏洞效率低下.如果要定向的查找漏洞,逆向跟踪变量技术就显得更加突出,如查找XSS.SQL注入.命令 ...

  5. idea导入myeclipes项目、运行项目

    1. 导入,部署: https://blog.csdn.net/u010570551/article/details/51510447 2. idea导入MyEclipse Web项目时,服务器搭建运 ...

  6. Liferay开发实战(1):入门

    网址: https://www.liferay.com/zh/ 文档: https://dev.liferay.com/develop 入门文章网上很多,中文的较少,存在版本太旧的问题,也缺少一步一步 ...

  7. odoo开发笔记 -- odoo仪表板集成hightcharts

    highcharts图表插件初探 http://www.cnblogs.com/liubei/p/highchartsOption.html

  8. Math.log()对数的妙用

    ###对数log 的妙用... formatBytes(bytes) { if (bytes === '0' || isNaN(bytes)) return ''; var s = ['Bytes', ...

  9. Task异步编程,刨根到底

    1. 编译器到底对await做了什么 await 一个异步操作的时候,实际上编译器会创建一个状态机,这个状态机包含了调用者的上下文变量,状态机使用yield迭代器实现,状态机由clr调度,每次运行都会 ...

  10. 课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 0、学习目标

    1. Build a logistic regression model, structured as a shallow neural network2. Implement the main st ...