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 - 主要保存个人的个性化设置,如命令别名.路径等 ...
随机推荐
- Linux软中断ksoftirqd
前言 在上一篇 LINUX软中断-softirq的描述中,提到过ksoftirqd,这篇文章就介绍ksoftirqd ksoftirqd 是什么? ksoftirqd 是个内核线程,在创建的时候是绑定 ...
- 使用SourceTree管理仓库代码
1.首先我们需要下载sourcetree,你可以去官网下载自己需要的版本. 2.安装完毕之后,我们需要获取ssh密钥与github关联上才能使用 按下面的操作开始执行.确定之后,会出现一个字符界面,输 ...
- 动态去读 dll 文件
// 反射动态读取 dll // Assembly assembly = Assembly.LoadFile(); 路径 // Assembly assembly = Assembly.LoadFro ...
- 如何解决token过期问题 ?
首先 token 过期会导致请求不到数据 , 就不能准确渲染页面 ,此时的错误配置项的token是过期的,只要更新了token 拿着原先的配置项重新请求数据即可 :但是如果更新token的时候请求错误 ...
- python中模块的概念以及常用模块
模块的概念:为了减少常用代码重复输入,同时方便多人协作,python中定义了模块一词. 模块是一些函数的集合.在python中可以使用import导入某一模块的单个或者所有功能. python中的模块 ...
- HTML常见的文本语义标签
列举HTML里一些常用的块内语义元素.可以通过F12来查看每个示例. <strong>:即"重点内容",通常是加粗,对应Markdown中的**加粗. 示例:归约数往往 ...
- 《JVM第6课》本地方法栈
1 什么是本地方法 首先要知道什么是本地方法,本地方法并不是 JVM 自己的方法,也不是 jre 里面的方法,而是指那些操作系统自己的方法(如C/C++方法),它们在操作系统目录里.可以这么理解,本地 ...
- 关于 PyCharm 2024安装使用 (附加永久激活码、补丁)
第一步:下载安装包 访问 IDEA 官网,下载安装包,下载链接如下 : https://www.jetbrains.com.cn/pycharm/ 第二步,安装完成之后,下载补丁 下载地址(里面包含激 ...
- Typecho框架个人博客搭建方法学习
使用Typecho框架一个月又十二天了,就目前感觉来说,整体还不错,很多方面都支持个性化,二次开发,但是目前MD编辑器有一丢丢问题,不能同步滚动条滚动,就是编辑器区域滚动,预览区域没有动静,需要两边都 ...
- 4年经验来面试20K的测试岗,连基础都不会,还不如招应届生。
公司前段时间缺人,也面了不少测试,结果竟然没有一个合适的.一开始瞄准的就是中级的水准,也没指望来大牛,提供的薪资在10-20k,面试的人很多,但平均水平很让人失望.看简历很多都是3.4年工作经验,但面 ...