先交代下背景,写《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;
}
}

(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/

关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!

版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信

声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

C#多线程之旅(7)——终止线程的更多相关文章

  1. java 多线程5: java 终止线程及中断机制 (stop()、interrupt() 、interrupted()、isInterrupted())

    JAVA中有3种方式可以终止正在运行的线程 ①线程正常退出,即run()方法执行完毕了 ②使用Thread类中的stop()方法强行终止线程.但stop()方法已经过期了,不推荐使用 ③使用中断机制i ...

  2. 多线程之旅(ThreadPool 线程池)

    一.什么是ThreadPool 线程池(源码) 1.线程池顾名思义,有我们的系统创建一个容器装载着我们的线程,由CLR控制的所有AppDomain共享.线程池可用于执行任务.发送工作项.处理异步 I/ ...

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

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

  4. 【C/C++多线程编程之四】终止pthread线程

    多线程编程之终止pthread线程       Pthread是 POSIX threads 的简称,是POSIX的线程标准.           终止线程似乎是多线程编程的最后一步,但绝不是本系列教 ...

  5. C#多线程编程实战1.4终止线程

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  6. java多线程系类:JUC线程池:03之线程池原理(二)(转)

    概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...

  7. Java多线程1:进程与线程概述

    进程和线程 谈到多线程,就得先讲进程和线程的概念. 进程 进程可以理解为受操作系统管理的基本运行单元.360浏览器是一个进程.WPS也是一个进程,正在操作系统中运行的".exe"都 ...

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

    源码地址:https://github.com/Jackson0714/Threads 原文地址:C#多线程之旅(4)——APM初探 C#多线程之旅目录: C#多线程之旅(1)——介绍和基本概念 C# ...

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

    原文地址:C#多线程之旅(1)——介绍和基本概念 C#多线程之旅目录: C#多线程之旅(1)——介绍和基本概念 C#多线程之旅(2)——创建和开始线程 C#多线程之旅(3)——线程池 C#多线程之旅( ...

随机推荐

  1. 前端学习数据库MYSQL

    这篇文章主要写了 1.数据库MYSQL 2.基本上会遇到的所有SQL语句 数据库可视化软件------Navicat 数据库里边存放的是表,表与表之间是有关联的,而且可以对表进行相关操作(增,删,改, ...

  2. Linux 程序,进程和线程

    进程如何使用内存. 当程序文件运行为进程时, 进程在内存中获得空间. 1) Text : 固定大小 存储指令(instruction), 说明每一步的操作. 2) Global Data : 固定大小 ...

  3. 使用dom4j讲xml字符串递归遍历成Map

    package test; import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import j ...

  4. 利用wamp配置虚拟主机

    第一步:打开wamp--Apache--httpd.conf找到# Virtual hosts 一行,把其下面的一行中的#去掉.

  5. Vue和Bootstrap的整合之路

    我是一个刚刚接触前端开发的新手,所以有必要记录如何将Bootstrap和Vue进行整合. 如果你是老手,请直接绕道而过.作为一个新手,里面的步骤,过程或者专业术语未必正确,如果你发现哪里错误了,请发邮 ...

  6. 最小的 Velocity 教程

    工作以后,我越来越能体会到80/20法则的强大. 这是一个不可否认的事实,常用 20% 的技术可以解决工作中 80% 的场景. 所以我希望能介绍给你 Velocity 技术 20%,帮助你胜任 80% ...

  7. dashDB - Introduction and DB Tools

    dashDB - Introduction dashDB is a database that is designed for performance and scale. It offers sea ...

  8. Mac之OS系统下搭建JavaEE环境 <五> 之Mysql数据库的安装及配置

    这里将推荐两款 集成的Mysql环境 十分轻便好用,MAMP 和 XAMPP MAMP XAMPP 1.MAMP下载 官网: https://www.mamp.info/en/ 下载安装即可使用 MA ...

  9. JavaWeb 后端 <十三> 之 监听器 JSTL国际化

    1. 监听器 1.1   概述 监听器: 主要是用来监听特定对象的创建或销毁.属性的变化的! 是一个实现特定接口的普通java类! 对象: 自己创建自己用 (不用监听) 别人创建自己用 (需要监听) ...

  10. 互联网级监控系统必备-时序数据库之Influxdb

    时间序列数据库,简称时序数据库,Time Series Database,一个全新的领域,最大的特点就是每个条数据都带有Time列. 时序数据库到底能用到什么业务场景,答案是:监控系统. Baidu一 ...