第七节:利用CancellationTokenSource实现任务取消和利用CancellationToken类检测取消异常。
一. 传统的线程取消
所谓的线程取消,就是线程正在执行的过程中取消线程任务。
传统的线程取消,是通过一个变量来控制,但是这种方式,在release模式下,被优化从cpu高速缓存中读取,而不是从内存中读取,会造成主线程无法执行这一个bug。
{
var isStop = false;
var thread = new Thread(() =>
{
while (!isStop)
{
Thread.Sleep();
Console.WriteLine("当前thread={0} 正在运行", Thread.CurrentThread.ManagedThreadId);
}
});
thread.Start();
Thread.Sleep();
isStop = true;
}

PS: 通过上面的代码看可以看出来,传统模式的线程取消,在排除release模式bug的情况下,局限性还是很明显的。比如:当子线程任务取消的那一刻,我想执行另外一项任务;我想延时取消一个线程任务;线程取消的时候抛异常。
上述这几种情况,我们都要借助单独的类来处理。
二. CancellationTokenSource实现任务取消
1. 取消任务的同时触发一个函数
利用Cancel方法、Register注册、source.Token标记取消位来实现。
{
CancellationTokenSource source = new CancellationTokenSource();
//注册一个线程取消后执行的逻辑
source.Token.Register(() =>
{
//这里执行线程被取消后的业务逻辑.
Console.WriteLine("-------------我是线程被取消后的业务逻辑---------------------");
});
Task.Run(() =>
{
while (!source.IsCancellationRequested)
{
Thread.Sleep();
Console.WriteLine("当前thread={0} 正在运行", Thread.CurrentThread.ManagedThreadId);
}
}, source.Token);
Thread.Sleep();
source.Cancel();
}

2. 延时取消
线程的延时取消有两种方式:
方案一:CancelAfter方法。
#region 方案一:CancelAfter方法
{
CancellationTokenSource source = new CancellationTokenSource();
//注册一个线程取消后执行的逻辑
source.Token.Register(() =>
{
//这里执行线程被取消后的业务逻辑.
Console.WriteLine("-------------我是线程被取消后的业务逻辑---------------------");
}); Task.Run(() =>
{
while (!source.IsCancellationRequested)
{
Thread.Sleep();
Console.WriteLine("当前thread={0} 正在运行", Thread.CurrentThread.ManagedThreadId);
}
}, source.Token); Thread.Sleep();
//4s后自动取消
source.CancelAfter(new TimeSpan(, , , ));
}
#endregion
方案二:CancellationTokenSource构造函数(不再需要Cancel方法了)。
{
//4s后自动取消
CancellationTokenSource source = new CancellationTokenSource();
//注册一个线程取消后执行的逻辑
source.Token.Register(() =>
{
//这里执行线程被取消后的业务逻辑.
Console.WriteLine("-------------我是线程被取消后的业务逻辑---------------------");
});
Task.Run(() =>
{
while (!source.IsCancellationRequested)
{
Thread.Sleep();
Console.WriteLine("当前thread={0} 正在运行", Thread.CurrentThread.ManagedThreadId);
}
}, source.Token);
Thread.Sleep();
}
3. 组合取消
利用CreateLinkedTokenSource构建CancellationTokenSource的组合体,其中任何一个体取消,则组合体就取消。
{
CancellationTokenSource source1 = new CancellationTokenSource();
//source1.Cancel();
CancellationTokenSource source2 = new CancellationTokenSource();
source2.Cancel();
var combineSource = CancellationTokenSource.CreateLinkedTokenSource(source1.Token, source2.Token);
Console.WriteLine("s1={0} s2={1} s3={2}", source1.IsCancellationRequested,
source2.IsCancellationRequested,
combineSource.IsCancellationRequested);
}
上述代码,source1和source2中的任何一个取消,combineSource就会被取消。

三. CancellationToken类监控取消
CancellationToken类下ThrowIfCancellationRequested属性,等价于if (XXX.IsCancellationRequested){throw new Exception("报错了");}
只要取消就报错。
{
CancellationTokenSource source1 = new CancellationTokenSource();
CancellationTokenSource source2 = new CancellationTokenSource();
var combineSource = CancellationTokenSource.CreateLinkedTokenSource(source1.Token, source2.Token);
source1.Cancel();
//if (combineSource.IsCancellationRequested)
//{
// throw new Exception("报错了");
//}
//等价于上面那句话
try
{
combineSource.Token.ThrowIfCancellationRequested();
}
catch (Exception)
{
Console.WriteLine("报错了");
}
Console.WriteLine("s1={0} s2={1} s3={2}", source1.IsCancellationRequested,
source2.IsCancellationRequested,
combineSource.IsCancellationRequested);
}

第七节:利用CancellationTokenSource实现任务取消和利用CancellationToken类检测取消异常。的更多相关文章
- centos Linux下磁盘管理 parted,df ,du,fdisk,partprobe,mkfs.ext4,mount,/etc/fstab,fsck,e2fsck,mk2efs,tmpfs ,nr_inodes, LVM,传统方式扩容文件系统 第七节课
centos Linux下磁盘管理 parted,df ,du,fdisk,partprobe,mkfs.ext4,mount,/etc/fstab,fsck,e2fsck,mk2efs,tmpf ...
- 基于Extjs的web表单设计器 第七节——取数公式设计之取数公式的使用
基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...
- JAVA 从GC日志分析堆内存 第七节
JAVA 从GC日志分析堆内存 第七节 在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...
- VUE2.0实现购物车和地址选配功能学习第七节
第七节 卡片选中,设置默认 1.卡片选中html:<li v-for="(item,index) in filterAddress" v-bind:class="{ ...
- delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行
第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行 以 Ado 为例,常见的方法是拖一个 AdoConnection 在窗口上(或 DataModule 中), 再配合 AdoQ ...
- J2EE进阶(七)利用SSH框架根据数据表建立model类
J2EE进阶(七)利用SSH框架根据数据表建立model类 前言 在利用SSH框架进行项目开发时,若将数据库已经建好,并且数据表之间的依赖关系已经确定,可以利用Hibernate的反转功能进行mode ...
- CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第七节
第七节:使用下一代CUDA硬件,快乐加速度 原文链接 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个 ...
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第七节:PS基础:UV动画
<使用Cocos2d-x 开发3D游戏>系列在线课程 第七节:PS基础:UV动画 视频地址:http://edu.csdn.net/course/attend/1330/20807 交流论 ...
- ES6 第七节 ES6中新增的数组知识(1)
目录 ES6 第七节 ES6中新增的数组知识(1) 第七节 ES6中新增的数组知识(1) JSON数组格式转换 Array.of()方法: find()实例方法: ES6 第七节 ES6中新增的数组知 ...
随机推荐
- bootstrap,bootstrap-table,bootstrapValidator,animate,layer配合起来搞事情
资源准备(just download) bootstrap: http://www.bootcss.com/ bootstrap-table: http://bootstrap-table.wenzh ...
- 我的第一个python web开发框架(23)——代码版本控制管理与接口文档
书接上一回,小白和老菜聊到代码的版本控制和接口文档 小白:为什么要做版本控制,我不弄版本控制不也完成了项目了吗?要做版本控制不是很麻烦,又要安装服务又要提交代码,代码又不是多人用开发,还要写文档... ...
- 在java web项目中实现随项目启动的额外操作
前言 在web项目中经常会遇到在项目启动初始,会要求做一些逻辑的实现,比如实现一个消息推送服务,实现不同类型数据同步的回调操作初始化,或则通知其他客户服务器本项目即将启动,等等.对于这种要求,目前个人 ...
- vs 2015安装包
Visual Studio 2015 下载含(更新3)及密钥 Visual Studio 2015 是一个丰富的集成开发环境,可用于创建出色的 Windows.Android 和 iOS 应用程序以及 ...
- Vue父组件向子组件传递一个动态的值,子组件如何保持实时更新实时更新?
原文:https://blog.csdn.net/zhouweixue_vivi/article/details/78550738 2017年11月16日 14:22:50 zhouweixue_vi ...
- R语言学习——处理数据对象的实用函数
length(object) # 显示对象中元素/成分的数量 dim(boject) # 显示某个对象的维度 str(object) # 显示某个对象的结构 class(object) # 显示某个对 ...
- keras 的 Deeplabv3+ 实现遇到的问题
代码大佬都已经写好了,具体参考:https://github.com/bonlime/keras-deeplab-v3-plus git clone 下来以后,按照指南要训练自己的数据集,只要设置好自 ...
- 字符串匹配KMP算法详解
1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...
- SystemCheckError: System check identified some issues: ERRORS: users.Test.groups: (fields.E304) Reverse accessor for 'Test.groups' clashes with reverse accessor for 'User.groups'.
Error Msg: SystemCheckError: System check identified some issues: ERRORS: users.Test.groups: (fields ...
- Fatal error: Call to undefined function json_decode()解决办法
最近搭建测试服务器,访问网站查看报错日志出现如下错误: Fatal error: Call to undefined function json_decode() 出现该问题原因是安装PHP时没有安装 ...