改善C#程序的建议7:正确停止线程
开发者总尝试对自己的代码有更多的控制。“让那个还在工作的线程马上停止下来”就是诸多要求中的一种。然而事与愿违,这里面至少存在两个问题:
第一个问题是:正如线程不能立即启动一样,线程也并不能说停就停。无论采用何种方式通知工作线程需要停止,工作线程都会忙完手头最紧要的活,然后在它觉得合适的时候退出。以最传统的Thread.Abort方法为例,如果线程当前正在执行的是一段非托管代码,那么CLR就不会抛出ThreadAbortException,只有当代码继续回到CLR中时,才会引发ThreadAbortException。当然,即便是在CLR环境中,ThreadAbortException也不会立即引发。
其次,正确停止线程,不在于调用者采取了什么行为(如最开始的Thread.Abort()方法),而更多依赖于工作线程是否能主动响应调用者的停止请求。大体机制是,如果线程需要被停止,那么线程自身就得负责开放给调用者这样的接口:Cancled,然后线程在工作的同时,还得以某种频率检测Cancled标识,若检测到Cancled,线程自己负责退出。
FCL现在为我们提供了标准的取消模式:协作式取消(Cooperative Cancellation)。协作式取消的机制就是上文提到的机制。下面是一个最基础的协作式取消的样例:
CancellationTokenSource cts =new CancellationTokenSource(); Thread t =new Thread(() => { while (true) { if (cts.Token.IsCancellationRequested) { Console.WriteLine("线程被终止!"); break; } Console.WriteLine(DateTime.Now.ToString()); Thread.Sleep(); } }); t.Start(); Console.ReadLine(); cts.Cancel();
调用者使用CancellationTokenSource的Cancle方法通知工作线程退出。工作线程则以大致1000毫秒的频率一边工作,一边检查是否有外界传入进来的Cancel信号。若有这样的信号,则负责退出。可以看到,在正确停止线程的机制中,真正起到主要作用的是线程本身。样例中的工作代码比较简单,不过也足以说明问题。更复杂的计算式的工作,也应该以这样的一种方式,妥善而正确地处理退出。
协作式取消中的关键类型是CancellationTokenSource。它有一个关键属性Token,Token是一个名为CancellationToken的值类型。CancellationToken继而进一步提供了布尔值的属性IsCancellationRequested作为需要取消工作的标识。CancellationToken还有一个方法尤其值得注意,那就是Register方法。它负责传递一个Action委托,在线程停止的时候被回调,使用方法如:
cts.Token.Register(() => { Console.WriteLine("工作线程被终止了。"); });
本建议中的例子使用Thread进行了演示,使用ThreadPool也是一样的模式,这里就不再赘述。后面我们还会讲到任务Task,它依赖于CancellationTokenSource和CancellationToken完成了所有的取消控制。
微信扫一扫,关注最课程(www.zuikc.com),获取更多我的文章,获取软件开发每日一练
之前的话题:
改善C#程序的建议6:在线程同步中使用信号量改善C#程序的建议5:引用类型赋值为null与加速垃圾回收改善C#程序的建议4:C#中标准Dispose模式的实现改善C#程序的建议3:在C#中选择正确的集合进行编码改善C#程序的建议2:C#中dynamic的正确用法改善C#程序的建议1:非用ICloneable不可的理由
改善C#程序的建议7:正确停止线程的更多相关文章
- 改善C#程序的建议6:在线程同步中使用信号量
原文:改善C#程序的建议6:在线程同步中使用信号量 所谓线程同步,就是多个线程之间在某个对象上执行等待(也可理解为锁定该对象),直到该对象被解除锁定.C#中对象的类型分为引用类型和值类型.CLR在这两 ...
- [No000017D]改善C#程序的建议6:在线程同步中使用信号量
所谓线程同步,就是多个线程之间在某个对象上执行等待(也可理解为锁定该对象),直到该对象被解除锁定.C#中对象的类型分为引用类型和值类型.CLR在这两种类型上的等待是不一样的.我们可以简单的理解为在CL ...
- 改善C#程序的建议10:用Parallel简化Task
在命名空间System.Threading.Tasks下,有一个静态类Parallel简化了在同步状态下的Task的操作.Parallel主要提供了3个有用的方法:For.ForEach.Invoke ...
- 改善C#程序的建议8:避免锁定不恰当的同步对象
原文:改善C#程序的建议8:避免锁定不恰当的同步对象 在C#中让线程同步的另一种编码方式就是使用线程锁.所谓线程锁,就是锁住一个资源,使得应用程序只能在此刻有一个线程访问该资源.可以用下面这句不是那么 ...
- 编写高质量代码改善C#程序的157个建议——建议77: 正确停止线程
建议77: 正确停止线程 开发者总尝试对自己的代码有更多的控制.例如,“让那个还在工作的线程马上停止下来”.然而,并非我们想怎样就可以怎样的,这至少涉及两个问题. 第一个问题 正如线程不能立即启动一样 ...
- [No000017E]改善C#程序的建议7:正确停止线程
开发者总尝试对自己的代码有更多的控制.“让那个还在工作的线程马上停止下来”就是诸多要求中的一种.然而事与愿违,这里面至少存在两个问题: 第一个问题是:正如线程不能立即启动一样,线程也并不能说停就停.无 ...
- [转]改善C#程序的建议4:C#中标准Dispose模式的实现
需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...
- 改善C#程序的建议1:非用ICloneable不可的理由
原文:改善C#程序的建议1:非用ICloneable不可的理由 好吧,我承认,这是一个反标题,实际的情况是:我找不到一个非用ICloneable不可的理由.事实上,接口ICloneable还会带来误解 ...
- 正确停止线程的方式三 使用Thread类中的内置的中断标记位-----------不熟悉
package charpter10; public class Processor implements Runnable { @Override public void run() { for ( ...
随机推荐
- color2gray 的实现
无论是 rgb 还是 yuv 等三通道的颜色空间中的像素点,将其转换为单通道(pixel_depth=255.)中的像素,一般情况下都是采用的对原始颜色空间的 3 通道的像素点线性组合而得到单通道的像 ...
- Change Sudoers Mod 777 To 0440
Method 1: > grub --> recovery mode --> e > ro single <--> rw single init=/bin/bash ...
- java-工具代码
格式化输出 //d:是输出整数 //10;表示输出10位整数 //0:表示如果不够10位的话,用0来占位,也可以用写成空格,用空格来占位 String a = String.format(" ...
- 一个git pull无法使用的问题
之前通过git管理的一个项目,今天直接用eclipse通过ssh加入工程后,每次通过git命令行pull代码都报以下错误: Unable to negotiate with 21.12.1.167 p ...
- Druid 专题
数据源配置: #datasource #Introductions: https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7 ...
- 经Gradle采取Jenkins的build
如今,企业都太多Jenkins去管理apk,后该代码被提交jenkins在生成build 因此,我们可以得到jenkins提交版本 Jenkins在编制job什么时候,有一个内置的可变BUILD_NU ...
- Android 平台下Cordova 调用Activity插件开发
首先建立一个包名为package com.JiajiaCy.CallActivity; package com.JajaCy.CallActivity; import org.apache.cordo ...
- C# 调用PowerShell方法
PowerShell应为编写和运行都很方便,所以为了重复利用,经常写了一些小方法或者PS代码片段.使用的时候可能会很难找到自己想要的那个方法,如果要是有一个界面把这些代码管理起来并且调用,那就很爽了 ...
- C#与西门子PLC通讯
1.0 通讯组件概述 通讯组件用于PC与可编程控制器(PLC).智能仪表等进行数据通讯,适用于基于PC高级语言的工业自动化控制系统.组件采用动态链接库文件(*.DLL)的形式,在PC系统的项目工程里 ...
- Exclusive access control to a processing resource
A data processing system is provided with multiple processors that share a main memory. Semaphore va ...