C# 使用CancellationTokenSource取消多线程
作者:⎛⎝≥⏝⏝≤⎛⎝⎛⎝≥⏝⏝≤⎛⎝ 发布时间:2023-11-15 00:31:54
有时间我们在使用多线程的时候,需要取消线程的执行,可以使用CancellationTokenSource来取消对Task开辟多线程的取消
如下:我们点击一个按钮开启线程,然后点击取消按钮取消该线程的执行
CancellationTokenSource cts ;
/// <summary>
/// 开启线程
/// </summary>
private void button1_Click(object sender, EventArgs e)
{
//重新实例化cts.Token就会不一样,不然再次点击的时候会报错,提示线程已经执行完毕
cts = new CancellationTokenSource();
Task task = new Task(() =>
{
Thread.Sleep(1500);
try
{
cts.Token.ThrowIfCancellationRequested();
MessageBox.Show("线程被执行");
}
catch (Exception ex)
{
MessageBox.Show("线程被取消");
}
}, cts.Token);
task.Start();
//如果放到这里有可能线程还没有开始执行就被取消了
//cts.Cancel(true);
}
/// <summary>
/// 取消线程
/// </summary>
private void button2_Click(object sender, EventArgs e)
{
cts.Cancel();
}
几点关键问题解释:
1:为什么线程里边去调用 Thread.Sleep(1500);
因为如果不让线程暂停一下,你在点击开启线程后。还没有来得及点击取消线程,线程都已经执行完毕了这个时候
再去取消线程是没有什么意义的。
2: cts.Cancel()
这句话其实只是设置一个状态,设置该对象一个熟悉为true而已,也就是设置cts.IsCancellationRequested为ture。
所以他根本没有真正的去取消线程的执行,只是设置一个状态而已。
3:cts.Token.ThrowIfCancellationRequested();
因为上面说的cts.Cancel()只是设置一个状态而已,线程不会真正被取消。其实线程开启后,现在都是要执行完的,
我们并不能真正去取消线程的执行,只是从逻辑上去取消线程需要处理的逻辑。
这句话的意思其实就是检查cts.Cancel()设置的属性状态,也就是cts.IsCancellationRequested是否为true,如果为
true就抛出一个异常,从而终止线程的执行
也就是说其实这句话完全可以我们自己来实现
同时取消多个线程:
同时取消多个线程,其实也很简单,我们不需要有多少个线程就去实例化多少个CancellationTokenSource,
多个线程绑定顶一个CancellationTokenSource的token然后调用该对象的cancel就可以同时取消多个线程了。
CancellationTokenSource cts;
/// <summary>
/// 开启线程
/// </summary>
private void button1_Click(object sender, EventArgs e)
{
//重新实例化cts.Token就会不一样,不然再次点击的时候会报错,提示线程已经执行完毕
cts = new CancellationTokenSource();
for (int i = 0; i < 5; i++)
{
Task task = new Task((obj) =>
{
Thread.Sleep(1500);
try
{
//cts.Token.ThrowIfCancellationRequested();
//检查状态,检查线程是否已经被取消,如果取消则自己跑出来一个线程
if (cts.Token.IsCancellationRequested)
throw new OperationCanceledException();
MessageBox.Show("线程" + obj + "被执行");
}
catch (Exception ex)
{
MessageBox.Show("线程" + obj + "被取消");
}
}, i, cts.Token);
task.Start();
}
//如果放到这里有可能线程还没有开始执行就被取消了
//cts.Cancel(true);
}
/// <summary>
/// 取消线程
/// </summary>
private void button2_Click(object sender, EventArgs e)
{
cts.Cancel();
}
来源:https://blog.csdn.net/aojiancc2/article/details/84063515


猜你喜欢
- 1.为什么要使用synchronized在并发编程中存在线程安全问题,主要原因有:1.存在共享数据 2.多线程共同操作共享数据。关键字syn
- 正则表达式 是一种匹配输入文本的模式。.Net 框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符和结构组成。接下来通过本
- Android 开发中Volley详解及实例最近在做项目的时候,各种get和post。简直要疯了,我这种啥都不了解的,不知道咋办了,然后百度
- 承蒙各位厚爱,我们一起每天进步一点点!(鼠标选中空白处查看答案)1、以下不属于构造方法特征的是()正确答案: D构造方法名与类名相同构造方法
- 本文实例讲述了C#使用Socket实现发送和接收图片的方法。分享给大家供大家参考。具体如下:using System;using Syste
- 目录一、泛型类型二、为什么需要泛型三、类型擦除四、类型擦除的后遗症五、Kotlin 泛型六、上界约束七、类型通配符 & 星号投影八、
- 说到网络,相信大家都对TCP、UDP和HTTP协议这些都不是很陌生,学习这部分应该先对端口、Ip地址这些基础知识有一定了解,后面我们都是直接
- 本文实例讲述了C#使用委托(delegate)实现在两个form之间传递数据的方法。分享给大家供大家参考。具体分析如下:关于Delegate
- Flutter 键值存储数据库键值存储是开发中十分常见的需求,在Flutter开发中,一般使用 shared_preferences 插件来
- 效果展示人脸支付效果视频密码框输入支付效果视频因为密码支付时会调起系统安全键盘,开启自动保护功能,防止泄露,会导致输入密码时录屏黑屏,故使用
- 属性问题引入前面我们已经在父工程中的dependencyManagement标签中对项目中所使用的jar包版本进行了统一的管理,但是如果在标
- 一、封装类1.封装类概念Java中存在基础数据类型,但是在某些情况下,我们要对基础数据类型进行对象的操作,例如,集合中只能存对象,而不能存在
- 本文实例讲述了Android编程实现下载时主界面与详细界面一致更新的方法。分享给大家供大家参考,具体如下:1、创建监听管理类public c
- 本文实例为大家分享了Android点击缩略图放大效果的具体代码,供大家参考,具体内容如下import android.animation.A
- 我们经常会希望在程序中写入一些配置信息,例如版本号,以及数据库的连接字符串等。你可能知道在WinForm应用程序中可以利用Propertie
- 这篇文章主要介绍了java通过Jsoup爬取网页过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 效果自定义密码输入框,项目的一个界面需求,我把这个自定义的输入框提取出来作为这次内容的题目。输入前: 输入后: 输入1个
- 本次和大家分享的是怎么来消费服务,上篇文章讲了使用Feign来消费,本篇来使用rest+ribbon消费服务,并且通过轮询方式来自定义了个简
- 井字棋游戏要求在3乘3棋盘上,每行都相同或者每列都相同再或者对角线相同,则胜出.因此我们可以使用一个二维数组来表示棋盘,判断胜负只需要判断数
- 前言最近的项目中需要用到VideoView实现视频播放,自己花了一天多时间才能出来,有点想打自己再见,在学校的时候没好好学。使用VideoV