C#中 CancellationTokenSource的妙用
在.NET中,CancellationTokenSource、CancellationToken和Task是处理异步操作和取消任务的重要工具。本文将通过一些简单的例子,帮助你理解它们的用法和协作方式。
CancellationTokenSource
CancellationTokenSource 是一个取消操作的触发器。它用于生成和管理CancellationToken,并控制取消信号的发出。
常用属性和方法
- Token: 返回一个与此源关联的
CancellationToken
。 - Cancel(): 触发取消操作。
- CancelAfter(milliseconds): 指定时间后触发取消操作。
- Dispose(): 释放资源。
示例
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
Task.Run(() => {
for (int i = 0; i < 10; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task canceled");
break;
}
Console.WriteLine($"Task running: {i}");
Thread.Sleep(500);
}
});
Thread.Sleep(2000);
cts.Cancel();
CancellationToken
CancellationToken 是用于传播取消请求的轻量级结构。它由CancellationTokenSource
生成。
常用属性和方法
- IsCancellationRequested: 是否收到取消请求。
- ThrowIfCancellationRequested(): 如果已请求取消,抛出
OperationCanceledException
。 - Register(Action): 注册一个取消时触发的回调。
示例
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
Task.Run(() => {
token.Register(() => Console.WriteLine("Cancellation registered"));
try
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested();
Console.WriteLine($"Task running: {i}");
Thread.Sleep(500);
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Task was canceled");
}
});
Thread.Sleep(2000);
cts.Cancel();
Task与CancellationToken
Task 是.NET中的异步操作单元。结合CancellationToken
可以在任务运行时取消它。
示例:取消任务
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
Task task = Task.Run(() => {
for (int i = 0; i < 10; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task canceled");
break;
}
Console.WriteLine($"Task running: {i}");
Thread.Sleep(500);
}
}, token);
Thread.Sleep(2000);
cts.Cancel();
try
{
task.Wait();
}
catch (AggregateException ex)
{
foreach (var inner in ex.InnerExceptions)
{
if (inner is TaskCanceledException)
{
Console.WriteLine("Task cancellation exception caught");
}
}
}
示例:带超时的任务
var cts = new CancellationTokenSource(3000); // 3秒后自动取消
CancellationToken token = cts.Token;
Task.Run(() => {
try
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested();
Console.WriteLine($"Task running: {i}");
Thread.Sleep(1000);
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Task canceled due to timeout");
}
});
小结
- 使用
CancellationTokenSource
来控制取消。 - 通过
CancellationToken
将取消信号传递给任务或方法。 - 任务中可以通过
ThrowIfCancellationRequested
或检查IsCancellationRequested
响应取消请求。 - 合理使用
Register
可以处理取消时的回调逻辑。
通过灵活运用这些工具,你可以编写更高效、可控的异步程序。
C#中 CancellationTokenSource的妙用的更多相关文章
- [转]Delphi中ShellExecute的妙用
Delphi中ShellExecute的妙用 ShellExecute的功能是运行一个外部程序(或者是打开一个已注册的文件.打开一个目录.打印一个文件等等),并对外部程序有一定的控制. ...
- 「Python实用秘技13」Python中临时文件的妙用
本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第12 ...
- shell中eval命令妙用——变量嵌套替换
eval命令妙用--变量嵌套替换 eval命令在Linux下的应用非常广泛,在写脚本的时候遇到一个变量嵌套的问题,用eval迎刃而解,略试不爽啊. var1="hello" i=1 ...
- C#中Dynamic的妙用及代码重构
应用场景:检查几个表的特定字段是否为空,字段是否为空是在数据库中进行配置的.前台根据数据中字段的设置,进行动态检查. 原始人版: private string CheckFieldNull(MONTH ...
- orcl 中decode的妙用
在不认识这个函数之前,我们要对同一张表或者同一查询语句块中的某一个字段进行计算分类统计时,要用到很多函数以及外连接.用这一函数往往可以解决很多复杂的东西. 网上的一段具有代表性的decode用法,不用 ...
- C++宏定义中"#"与"##"的妙用
在C++开发当中经常用到宏的定义当中使用"#"或者"##",以下是对着两种符号使用方法的简单描述: define中的#就是把#后面的参数当做一个符号来使用,简单 ...
- 【jquery】javaScript中prototype的妙用 巧妙运用prototype属性原型链创建对象
prototype 可以有好多有优化实现方法 http://blog.csdn.net/liuqiwen0512/article/details/8089690 在 JavaScript 中,每个函 ...
- mysql中pager命令妙用
pager命令的妙用在mysql,可以大大提高工作效率. 一 当处理大量数据时,不想显示查询的结果,而只需知道查询话费的时间. mysql> select * from t3; +----- ...
- Delphi中ShellExecute的妙用
ShellExecute的功能是运行一个外部程序(或者是打开一个已注册的文件.打开一个目录.打印一个文件等等),并对外部程序有一定的控制.有几个API函数都可以实现这些功能,但是在大多数情况下Shel ...
- linux系统中.bashrc的妙用
一.有何作用 .bashrc - The individual per-interactive-shell startup file. .bashrc - 主要保存个人的个性化设置,如命令别名.路径等 ...
随机推荐
- WebBrowser中打开新页面
要求新打开的网页受控于WebBrowser 解决办法很简单,分两情况,一是在当前WebBrowser中打开新页面,二是在新Form中的WebBrowser中打开新页面: public Form1() ...
- C#中测试普通方法和对象类型以及泛型所需要的时间
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Re:从零开始的pwn学习(栈溢出篇)
写在前面:本文旨在帮助刚接触pwn题的小伙伴少走一些弯路,快速上手pwn题,内容较为基础,大佬轻喷.本文默认读者明白最基础的汇编指令的含义,并且已经配置好linux64位环境,明白基础的Linux指令 ...
- 从0.1开始学java(2)
string串池 现在都在堆中 "=="号的比较 字符串比较一般调用equals或者equalsignoreCase API来比较(后者忽略大小写) StringBuilder 可 ...
- 登陆mysql,Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2) "
今天ssh到slave机器上,登陆mysql,遇到下图的报错. 查了一圈,最终解决办法简洁的出乎意料. 首先,要查看mysql服务是否已经启动(真的太容易漏掉) 第2步,你可能会自然而然的以为密码也是 ...
- Mellanox hp 544+FLR QSFP 40G 网卡升级固件及性能测试
烧录命令参考视频: 相关视频: https://www.youtube.com/watch?v=_2-qPV1giEc flint -allow_psid_change -d /dev/mst/mt4 ...
- 用Python创建一个简单的Web服务器
基本思路: 在浏览器地址栏通过输入本机地址:http://127.0.0.1:8000 能够访问我们自己创建的Web服务器,并且给浏览器返回一句Hello World 代码实现: 1 import s ...
- 循环中拼接String不同方法性能耗时对比
对比背景 Java中最常用的拼接字符串方法就是 + 或 +=,使用上简单方便.但如果拼接数量比较大,例如在循环中拼接字符串,可能会有性能问题: 测试数据 循环100000次进行String拼接,对比+ ...
- MoD:轻量化、高效、强大的新型卷积结构 | ACCV'24
来源:晓飞的算法工程笔记 公众号,转载请注明出处 论文: CNN Mixture-of-Depths 论文地址:https://arxiv.org/abs/2409.17016 创新点 提出新的卷积轻 ...
- apisix启动报错undefined symbol: EVP_KDF_ctrl, version OPENSSL_1_1_1b
报错内容 2024/08/06 16:56:13 [error] 154236#154236: *7039 [lua] plugin.lua:110: load_plugin(): failed to ...