C# CancellationTokenSource的用法 - 如何优雅地取消异步任务
发布时间:2025-12-05 15:48
发布者:网络
浏览次数:CancellationTokenSource 与 CancellationToken 配合实现协作式取消:前者发起取消请求,后者传递并监听信号,异步方法通过轮询或 ThrowIfCancellationRequested 响应,抛出 OperationCanceledException 终止执行。

在C#中处理异步操作时,经常需要支持取消功能。比如用户点击“取消”按钮、超时或切换页面时,正在运行的异步任务应能及时停止,避免资源浪费和潜在错误。CancellationTokenSource 正是为此设计的核心机制,它与 CancellationToken 配合使用,实现对异步任务的优雅取消。
1. CancellationToken 和 CancellationTokenSource 的关系
CancellationTokenSource 是取消请求的发起者,通过调用其 Cancel() 方法发出取消通知。而 CancellationToken 是一个轻量结构体,由 CancellationTokenSource 创建并传递给异步方法,用于监听是否收到取消请求。
异步方法通过轮询或注册回调来响应取消令牌,一旦检测到取消信号,就停止执行并抛出 OperationCanceledException,从而实现协作式取消(cooperative cancellation)。
示例代码:
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
// 启动异步任务并传入取消令牌
Task.Run(async () =>
{
try
{
await DoWorkAsync(token);
}
catch (OperationCanceledException)
{
Console.WriteLine("任务已被取消");
}
}, token);
// 模拟外部触发取消
cts.Cancel(); // 发起取消
2. 在异步方法中响应取消令牌
大多数内置异步方法(如 HttpClient.GetAsync、Stream.ReadAsync 等)都接受 CancellationToken 参数,会自动响应取消请求。在自定义异步逻辑中,需手动检查令牌状态。
常用方式包括:
拾贝
一键同步微信读书所有笔记和划线,并在新标签页回顾
186
查看详情
- 将 token 传给支持取消的 API
- 调用 token.ThrowIfCancellationRequested() 主动抛出异常
- 在循环中检查 token.IsCancellationRequested
private async Task DoWorkAsync(CancellationToken token)
{
for (int i = 0; i < 100; i++)
{
// 模拟耗时操作
await Task.Delay(100, token); // Delay 支持取消
// 手动检查(可选)
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}
Console.WriteLine($"处理进度: {i + 1}%");
}
}
3. 设置超时自动取消
CancellationTokenSource 支持在构造时指定超时时间,超时后自动触发取消,无需手动调用 Cancel()。
// 5秒后自动取消
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
try
{
await LongRunningOperationAsync(cts.T
oken);
}
catch (OperationCanceledException)
{
Console.WriteLine("操作因超时被取消");
}
4. 取消多个任务或组合取消条件
如果需要监听多个取消源,可以使用 CancellationTokenSource.CreateLinkedTokenSource 链接多个令牌。
var cts1 = new CancellationTokenSource(); var cts2 = new CancellationTokenSource(); // 创建联合令牌 using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token); var token = linkedCts.Token; // 任意一个源取消,linkedCts 就会触发 await Task.Run(() => DoWorkAsync(token), token); cts1.Cancel(); // 触发取消
这种模式适用于页面级取消 + 超时取消的场景。
5. 使用注意事项
- 始终在可能的地方传递 CancellationToken,尤其是 I/O 操作
- 使用 using 声明或 try-finally 确保 CancellationTokenSource 被释放
- 捕获 OperationCanceledException 是正常流程,不应视为错误
- 不要强行终止线程,应依赖协作式取消
基本上就这些。合理使用 CancellationTokenSource 能让异步代码更健壮、响应更快,也能提升用户体验。关键是把取消作为一种协作行为,而不是强制中断。
以上就是C# CancellationTokenSource的用法 - 如何优雅地取消异步任务的详细内容,更多请关注其它相关文章!
# go
# ai
# nas
# stream
# 异步任务
# c#
# 令牌
# 多个
# 拾贝
# 抛出
# 有哪些
# 你在
# 自定义
# 发展趋势
# 游戏开发
# 新特性
# 外贸网站建设cms
# 推广营销方案封面设计怎么写
# 帝国影视网站建设管理
# 上饶网络营销怎么推广的
# 网络营销广告推广重要吗
# 建设网站报价表
# 酒店seo销售
# 网站页面排版优化设计
# 莱西网站优化多少钱
# 营销推广连接





oken);
}
catch (OperationCanceledException)
{
Console.WriteLine("操作因超时被取消");
}