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
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java操作excel的三种常见方法实例
![](https://img.aspxhome.com/file/2023/2/77362_0s.png)
android自定义简单时钟
![](https://img.aspxhome.com/file/2023/5/123265_0s.jpg)
c#消息提示框messagebox的详解及使用
spring-boot-autoconfigure模块用法详解
![](https://img.aspxhome.com/file/2023/8/60198_0s.png)
详解怎么用Java的super关键字
![](https://img.aspxhome.com/file/2023/7/86807_0s.png)
Android自带emoji表情的使用方法详解
![](https://img.aspxhome.com/file/2023/7/94967_0s.png)
Java 中的变量类型
Android三级缓存原理讲解
![](https://img.aspxhome.com/file/2023/4/139554_0s.png)
Java中如何动态创建接口的实现方法
![](https://img.aspxhome.com/file/2023/9/60259_0s.png)
android shape实现阴影或模糊边效果
![](https://img.aspxhome.com/file/2023/1/137821_0s.png)
Flutter Recovering Stream Errors小技巧
![](https://img.aspxhome.com/file/2023/8/137788_0s.jpg)
Kotlin Flow封装类SharedFlow StateFlow LiveData使用对比
![](https://img.aspxhome.com/file/2023/1/138541_0s.jpg)
Logback 使用TurboFilter实现日志级别等内容的动态修改操作
Java 数据结构深入理解ArrayList与顺序表
![](https://img.aspxhome.com/file/2023/1/62501_0s.png)
SpringBoot使用AOP+注解实现简单的权限验证的方法
Java 静态绑定与动态绑定深入分析
详解Java中用于查找对象哈希码值的hashCode()函数
IntelliJ IDEA(2020.2)的下载、安装步骤详细教程
![](https://img.aspxhome.com/file/2023/0/59900_0s.png)
使用maven的profile构建不同环境配置的方法
![](https://img.aspxhome.com/file/2023/1/125611_0s.png)