在C#中,
CancellationToken是取消异步操作的标准、安全且协作式的方式。它本身不强制终止线程或任务,而是通过“通知”机制让异步方法主动检查并优雅退出。
传递 CancellationToken 到异步方法
大多数内置异步方法(如
HttpClient.GetAsync、
Stream.ReadAsync、
Task.Delay)都支持接收
CancellationToken参数。只要传入,它们会在内部监听取消信号,并在触发时抛出
OperationCanceledException(通常无需手动捕获,除非需特殊处理)。 直接传入:确保调用时把 token 作为最后一个参数传进去 示例:
await httpClient.GetAsync("https://api.example.com", cancellationToken);
若方法未提供 token 重载,说明它不支持协作取消,需考虑封装或改用支持的方法
在自定义异步逻辑中手动检查取消
写自己的
async方法时,需定期调用
cancellationToken.ThrowIfCancellationRequested()或检查
cancellationToken.IsCancellationRequested,尤其在长时间运行或循环中。 推荐用
ThrowIfCancellationRequested():简洁且与系统行为一致 避免只靠
IsCancellationRequested却不抛异常——这会让调用方无法统一捕获取消状态 示例片段:
for (int i = 0; i < 100; i++)<br>{<br> cancellationToken.ThrowIfCancellationRequested();<br> await Task.Delay(100, cancellationToken); // 这里也传 token<br>}
创建和触发 CancellationToken
通常用
CancellationTokenSource创建 token 并控制取消。它是一次性对象,调用
Cancel()后所有关联的 token 都会进入已取消状态。 基本用法:
var cts = new CancellationTokenSource();,然后传
cts.Token给异步方法 可设超时:
new CancellationTokenSource(TimeSpan.FromSeconds(5)),时间到自动取消 记得适时调用
cts.Dispose()(尤其在 using 块中),释放底层资源 不要重复调用
Cancel();多次调用无害但没必要
处理取消异常与资源清理
取消引发的
OperationCanceledException是正常流程的一部分。建议按需捕获,但不要“吞掉”它而不做响应——否则可能掩盖真实取消意图。 如果想区分取消和其他异常,可用
catch (OperationCanceledException) when (e.CancellationToken == myToken)在
finally或
using中做必要清理(如关闭流、释放句柄) 注意:被取消的
Task状态是
TaskStatus.Canceled,不是
Faulted
基本上就这些。核心是“协作”而非“强制”,关键在于方法签名支持、token 正确传递、及时检查、合理清理。用对了,异步取消既可靠又干净。
