0

0

c# CancellationToken 的用法 c#如何取消一个异步任务

月夜之吻

月夜之吻

发布时间:2025-12-29 17:23:27

|

281人浏览过

|

来源于php中文网

原创

CancellationToken 本身不能取消任务,只是传递取消信号;真正取消依赖代码主动响应——检查 token 并抛出 OperationCanceledException 或提前退出。

c# cancellationtoken 的用法 c#如何取消一个异步任务

直接说结论:CancellationToken 本身不能“取消”任务,它只是个信号令牌;真正实现取消的是你写的代码是否响应这个信号——不检查、不抛异常、不退出,Cancel() 就是按了个静音键。

怎么创建和传递 CancellationToken?

核心就三步:建 CancellationTokenSource → 拿 Token → 往异步方法里传。绝大多数内置异步 API(比如 HttpClient.GetAsyncStreamReader.ReadLineAsync)都支持接收 CancellationToken 参数,这是约定俗成的最后一个可选参数。

  • CancellationTokenSource 是“发号施令的人”,调用 Cancel()CancelAfter(3000) 就是下命令
  • CancellationToken 是“传令兵”,只读、不可变,任务靠它轮询或注册回调
  • 别自己 new CancellationToken —— 必须从 CancellationTokenSource.Token 获取

为什么 await HttpClient.GetAsync(token) 会真的被取消?

因为 HttpClient 内部做了响应:它在底层 socket 操作中监听了 token.IsCancellationRequested,一旦为 true 就立即中断请求并抛出 OperationCanceledException。这不是魔法,是微软在 SDK 里写死了的协作逻辑。

  • 你用的大多数 .NET 基础类库(FileStreamTask.DelayTimer 等)都原生支持 CancellationToken
  • 但你自己写的长循环、CPU 密集型计算、或调用非托管代码时,必须手动检查,否则取消完全无效
  • 错误写法:await Task.Delay(1000); —— 没传 token,就无法被外部中断
  • 正确写法:await Task.Delay(1000, token); 或在循环中加 token.ThrowIfCancellationRequested();

常见踩坑:取消后任务还在跑、没进 catch、资源没释放

最典型的问题不是“不会用”,而是“用了但没全覆盖”。比如在 try 里开了文件流、连了数据库,却只在 await 处检查 token,忘了在 finally 或 using 外做清理。

Z Code
Z Code

智谱AI推出的轻量级AI代码编辑器

下载
  • OperationCanceledException 是正常流程,不是 bug,应该显式 catch 并区分处理(比如不记日志、不弹错误框)
  • 别在 catch (Exception) 里吞掉 OperationCanceledException,否则你永远不知道任务是不是被取消了
  • 要用 token.Register(() => { /* 清理资源 */ }) 注册回调,尤其当取消可能发生在非 await 路径(如同步计算中途)
  • 超时场景优先用 new CancellationTokenSource(TimeSpan.FromSeconds(5)),比手写定时器 + Cancel() 更可靠
static async Task LongRunningOperationAsync(CancellationToken token)
{
    using var registration = token.Register(() => Console.WriteLine("已触发取消回调,释放资源"));
for (int i = 0; i zuojiankuohaophpcn 100; i++)
{
    token.ThrowIfCancellationRequested(); // 关键:主动抛异常,让调用栈快速退出
    await Task.Delay(100, token);          // 关键:所有 await 都带 token
    Console.WriteLine($"进度: {i + 1}%");
}

}

真正难的从来不是怎么写 cts.Cancel(),而是想清楚:你的业务逻辑里,哪些步骤可中断、哪些必须原子完成、哪些资源必须确保释放——CancellationToken 只提供机制,不替你做决策。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6033

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

779

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1044

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1073

2024.03.01

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

330

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2068

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

346

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

251

2023.09.05

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号