一. 传统的线程取消

  所谓的线程取消,就是线程正在执行的过程中取消线程任务。

  传统的线程取消,是通过一个变量来控制,但是这种方式,在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类检测取消异常。的更多相关文章

  1. 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 ...

  2. 基于Extjs的web表单设计器 第七节——取数公式设计之取数公式的使用

    基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...

  3. JAVA 从GC日志分析堆内存 第七节

    JAVA 从GC日志分析堆内存 第七节   在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...

  4. VUE2.0实现购物车和地址选配功能学习第七节

    第七节 卡片选中,设置默认 1.卡片选中html:<li v-for="(item,index) in filterAddress" v-bind:class="{ ...

  5. delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行

    第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行     以 Ado 为例,常见的方法是拖一个 AdoConnection 在窗口上(或 DataModule 中), 再配合 AdoQ ...

  6. J2EE进阶(七)利用SSH框架根据数据表建立model类

    J2EE进阶(七)利用SSH框架根据数据表建立model类 前言 在利用SSH框架进行项目开发时,若将数据库已经建好,并且数据表之间的依赖关系已经确定,可以利用Hibernate的反转功能进行mode ...

  7. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第七节

    第七节:使用下一代CUDA硬件,快乐加速度 原文链接 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个 ...

  8. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第七节:PS基础:UV动画

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第七节:PS基础:UV动画 视频地址:http://edu.csdn.net/course/attend/1330/20807 交流论 ...

  9. ES6 第七节 ES6中新增的数组知识(1)

    目录 ES6 第七节 ES6中新增的数组知识(1) 第七节 ES6中新增的数组知识(1) JSON数组格式转换 Array.of()方法: find()实例方法: ES6 第七节 ES6中新增的数组知 ...

随机推荐

  1. LeetCode算法题-Average of Levels in Binary Tree(Java实现)

    这是悦乐书的第277次更新,第293篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第145题(顺位题号是637).给定一个非空二叉树,以数组的形式返回每一层节点值之和的平 ...

  2. 我的第一个python web开发框架(23)——代码版本控制管理与接口文档

    书接上一回,小白和老菜聊到代码的版本控制和接口文档 小白:为什么要做版本控制,我不弄版本控制不也完成了项目了吗?要做版本控制不是很麻烦,又要安装服务又要提交代码,代码又不是多人用开发,还要写文档... ...

  3. 怎样保证socket.recv接收完数据

    最近在使用python进行网络编程开发一个通用的tcpclient测试小工具.在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题.这 ...

  4. 第一节 anaconda+jupyter+numpy简单使用

    数据分析:是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律 数据分析三剑客:Numpy,Pandas,Matplotlib 一 Anaconda 1 下载 官网:http ...

  5. python购物车demo

    product_list = [        ('Iphone',11800),        ('Mac Pro',13800),        ('BMW CAR',480000),      ...

  6. 【转】SpringBoot启动服务的三种方式

    1.IDEA启动 2.命令行启动 首先将命令行位置跳转到当前项目的根目录下,再输入“mvn spring-boot:run”命令,初次操作maven需要下载插件等待几分钟 3.命令行编译为jar启动 ...

  7. RPC----Hadoop核心协议

    什么是RPC RPC设计的目的 RPC的作用 远程过程调用(RPC)是一个协议,程序可以使用这个协议请求网络中另一台计算机上某程序的服务而不需要知道网络细节. 必备知识: 网络七层模型 网络四层模型 ...

  8. 【学习总结】GirlsInAI ML-diary day-17-初始dataframe

    [学习总结]GirlsInAI ML-diary 总 原博github链接-day17 认识dataframe 一种非常有用的数据类型,叫做"DataFrame",经常缩写为&qu ...

  9. NOIP2015普及组复赛A 推销员

    题目链接:https://ac.nowcoder.com/acm/contest/243/A 题目大意: 略 分析: 方法就是把疲劳值从小到大排个序,然后从尾部开始一个一个取,当选到第i(i > ...

  10. BZOJ3498PA2009 Cakes——三元环

    题目描述 N个点m条边,每个点有一个点权a.对于任意一个三元环(j,j,k)(i<j<k),它的贡献为max(ai,aj,ak) 求所有三元环的贡献和.N<100000,,m< ...