我们在多线程中通常使用一个bool IsExit类似的代码来控制是否线程的运行与终止,其实使用CancellationTokenSource来进行控制更为好用,下面我们将介绍CancellationTokenSource相关用法。

C# 使用 CancellationTokenSource 终止线程

使用CancellationTokenSource对象需要与Task对象进行配合使用,Task会对当前运行的状态进行控制(这个不用我们关心是如何孔控制的)。而CancellationTokenSource则是外部对Task的控制,如取消、定时取消。

下面我们来看看示例代码

    class Program
{
//声明CancellationTokenSource对象
static CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); //程序入口
static void Main(string[] args)
{
Task.Factory.StartNew(MyTask, cancelTokenSource.Token); Console.WriteLine("请按回车键(Enter)停止");
Console.ReadLine(); cancelTokenSource.Cancel(); Console.WriteLine("已停止");
Console.ReadLine();
} //测试方法
static void MyTask()
{
//判断是否取消任务
while (!cancelTokenSource.IsCancellationRequested)
{
Console.WriteLine(DateTime.Now);
Thread.Sleep(1000);
}
}
}

Task.Factory.StartNew 创建并启动了 MyTask 方法,并传递了一个 CancellationTokenSource.Token 对象进去。我们可以通过在外部CancellationTokenSource对象进行控制是否取消任务的运行。

当在 MyTask 中的 cancelTokenSource.IsCancellationRequested 判断如果是取消了任务的话 就跳出while循环执行。也就结束了任务

我们还可以使用计时取消任务,当一个任务超过了我们所设定的时间然后自动取消该任务的执行。如下代码所示

var cancelTokenSource = new CancellationTokenSource(3000);

除了构造函数,我们还可以使用另外一种方式实现定时取消,如下代码所示

cancelTokenSource.CancelAfter(3000);

运行起来效果是一样的,3秒钟定时取消。

多个 CancellationTokenSource 复合

在有多个CancellationTokenSource需要一起并行管理的时候,比如任意一个任务取消 则取消所有任务。我们不必去一个一个的去关闭,只需要将需要一起并行关闭的CancellationTokenSource组合起来就行了。如下代码所示,执行结果是跟上面的图一样的。我就不再上图了。

    class Program
{
//声明CancellationTokenSource对象
static CancellationTokenSource c1 = new CancellationTokenSource();
static CancellationTokenSource c2 = new CancellationTokenSource();
static CancellationTokenSource c3 = new CancellationTokenSource(); //使用多个CancellationTokenSource进行复合管理
static CancellationTokenSource compositeCancel = CancellationTokenSource.CreateLinkedTokenSource(c1.Token, c2.Token, c3.Token); //程序入口
static void Main(string[] args)
{
Task.Factory.StartNew(MyTask, compositeCancel.Token); Console.WriteLine("请按回车键(Enter)停止");
Console.ReadLine(); //任意一个 CancellationTokenSource 取消任务,那么所有任务都会被取消。
c1.Cancel(); Console.WriteLine("已停止");
Console.ReadLine();
} //测试方法
static void MyTask()
{
//判断是否取消任务
while (!compositeCancel.IsCancellationRequested)
{
Console.WriteLine(DateTime.Now);
Thread.Sleep(1000);
}
}
}

以上代码调用了​

c1.Cancel();

触发了​

​MyTask()

​方法中的​

compositeCancel.IsCancellationRequested​

为true,则取消了任务。所以我们在所有任务中判断复合的这个CancellationTokenSource对象即可。

C# 教你如何终止Task线程的更多相关文章

  1. java 线程的终止与线程中断

    关于线程终止: 1.一般来讲线程在执行完毕后就会进入死亡状态,那该线程自然就终止了. 2.一些服务端的程序,可能在业务上需要,常驻系统.它本身是一个无穷的循环,用于提供服务.那对于这种线程我们该如何结 ...

  2. 安全终止MFC线程

    终止线程 有两种情况可以使线程结束:控制函数结束或者根本就不允许线程完成,而提前终止它.我们可以想象在WORD中进行后台打印,如果打印结束了,那线程就可以结束了.如果用户中止了打印,那后台打印线程也要 ...

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

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

  4. 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---干净的终止一个线程

    干净的终止一个线程  我曾经在第2章产生一个后台线程,用以输出一张屏幕外的 bitmap 图.我们必须解决的一个最复杂的问题就是,如果用户企图结束程序,而这张bitmap 图尚未完成,怎么办?第2章的 ...

  5. java 线程实现、线程暂停和终止 、线程联合join、线程基本信息获取和设置、线程优先级

    转载地址:速学堂 https://www.sxt.cn/Java_jQuery_in_action/eleven-inheritthread.html 1. 通过继承Thread类实现多线程 继承Th ...

  6. C#/WPF 使用的Task线程程序缺依旧响应缓慢问题

    问题:C#/WPF 使用的Task线程程序缺依旧响应缓慢问题 摘要:相信很多做WPF的开发者在请求接口的时候会去采用开一个线程Task去请求接口.避免UI卡主等等.但有一个问题是但开的线程比较多的情况 ...

  7. 如何终止java线程

    http://blog.csdn.net/anhuidelinger/article/details/11746365 终止线程的三种方法 有三种方法可以使终止线程. 1.  使用退出标志,使线程正常 ...

  8. Task线程 同时执行多个任务

    Task taskTest = Task.Factory.StartNew(() => { Console.WriteLine("); },TaskCreationOptions.No ...

  9. 干货 | 教你如何监控 Java 线程池运行状态

    之前写过一篇 Java 线程池的使用介绍文章<线程池全面解析>,全面介绍了什么是线程池.线程池核心类.线程池工作流程.线程池分类.拒绝策略.及如何提交与关闭线程池等. 但在实际开发过程中, ...

  10. 干货:教你如何监控 Java 线程池运行状态

    之前写过一篇 Java 线程池的使用介绍文章<线程池全面解析>,全面介绍了什么是线程池.线程池核心类.线程池工作流程.线程池分类.拒绝策略.及如何提交与关闭线程池等. 但在实际开发过程中, ...

随机推荐

  1. C++Day12 虚拟继承内存布局测试

    测试一.虚继承与继承的区别 1.1 单个继承,不带虚函数 1>class B size(8): 1> +--- 1> 0 | +--- (base class A) 1> 0 ...

  2. 反射_Class对象功能概述-反射_Class对象功能_获取Field

    反射_Class对象功能概述 * Class对象功能: * 获取功能: 1. 获取成员变量们 * Field[] getFields() :获取所有public修饰的成员变量 * Field getF ...

  3. 存储自定义类型元素-LinkedHashSet集合

    存储自定义类型元素 HashSet存储自定义类型元素 set集合报错元素唯一: 存储的元素(String,Integer,...,Student,Person...),必须重写hashCode方法和e ...

  4. Argus 与其他(非Oracle B2B)EDI 工具的集成

    Argus 是Oracle 的产品,它自然推荐使用Oracle 自己的EDI 系统,这个系统就是Oracle B2B.但是Argus 留有与其他EDI 工具的集成空间,即即使不使用Oracle B2B ...

  5. Django中需要修改配置

    Django需要修改配置 1.修改templates中的路径配置: TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.Django ...

  6. 一个关于DOM的小小思考

    在学习过程中碰见这样一个方法(原生JavaScript可使用的方法): document.querySelector('div').innerHTML=` <h2>编号:${resp.id ...

  7. 微服务学习计划——SpringCloud

    微服务学习计划--SpringCloud 在学习并掌握了众多基础框架之后,我们的项目繁杂且难以掌握,那么我们就需要开启一门新的课程,也就是我们常说的微服务架构 随着互联网行业的发展,对服务的要求也越来 ...

  8. 定位bug

    软件测试阶段:单元测试,集成测试,系统测试,验收测试 测试人员参与的软件测试阶段一般来说只有集成测试和系统测试阶段.集成测试阶段主要测试的是接口:系统测试阶段主要是功能测试,兼容性测试等,涉及到定位b ...

  9. .net gRPC初探 - 从一个简单的Demo中了解并学习gRPC

    一..NET 上的 gRPC 的简介 gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架. gRPC 的主要优点是: 现代高性能轻量级 RPC 框架. 协定优先 API 开发,默认使用协 ...

  10. CMAKE添加库

    1.因为pthread不是C标准库,需要链接 2.在CMakeLists.txt里添加: FIND_PACKAGE(Threads  REQUIRED) TARGET_LINK_LIBRARIES($ ...