当前位置:首页 > C# > 正文

掌握CancellationToken:优雅终止C#异步任务(.NET取消令牌实战指南)

在现代C#开发中,异步编程已成为处理耗时操作(如网络请求、文件读写等)的标准方式。然而,当用户取消操作或系统需要提前终止任务时,如何安全、高效地停止正在运行的异步任务?答案就是使用 CancellationToken —— .NET 提供的强大取消机制。

掌握CancellationToken:优雅终止C#异步任务(.NET取消令牌实战指南) CancellationToken  C#任务取消 异步编程 .NET取消令牌 第1张

什么是 CancellationToken?

CancellationToken 是 .NET 中用于协作式取消操作的核心类型。它本身不强制终止线程或任务,而是通过“信号”通知任务:用户或系统希望取消当前操作。任务代码需主动检查该信号并做出响应。

这种设计避免了强制终止带来的资源泄漏或状态不一致问题,是 C#任务取消 的最佳实践。

基本使用步骤

  1. 创建 CancellationTokenSource(简称 CTS),它是生成取消令牌的源头。
  2. 从 CTS 获取 CancellationToken 并传递给异步方法。
  3. 在异步方法内部定期检查 token.IsCancellationRequested 或调用 token.ThrowIfCancellationRequested()
  4. 当需要取消时,调用 cts.Cancel() 发出取消信号。

完整代码示例

下面是一个简单但完整的控制台程序,演示如何使用 .NET取消令牌 安全终止一个长时间运行的任务:

using System;using System.Threading;using System.Threading.Tasks;class Program{    static async Task Main(string[] args)    {        // 1. 创建 CancellationTokenSource        var cts = new CancellationTokenSource();        // 2. 启动一个可取消的异步任务        var task = DoWorkAsync(cts.Token);        Console.WriteLine("按任意键取消任务...");        Console.ReadKey();        // 3. 请求取消        cts.Cancel();        Console.WriteLine("已请求取消任务。");        try        {            // 4. 等待任务完成(可能正常结束,也可能因取消而抛出异常)            await task;        }        catch (OperationCanceledException ex)        {            Console.WriteLine($"任务被成功取消: {ex.Message}");        }        Console.WriteLine("程序结束。");    }    static async Task DoWorkAsync(CancellationToken token)    {        for (int i = 0; i < 100; i++)        {            // 检查是否请求取消            token.ThrowIfCancellationRequested();            // 模拟工作            await Task.Delay(500, token); // 注意:Task.Delay 也支持传入 token            Console.WriteLine($"已完成 {i + 1}%");        }        Console.WriteLine("任务完成!");    }}

关键点解析

  • 协作式取消:任务必须主动检查 CancellationToken,否则即使调用了 Cancel() 也不会生效。
  • ThrowIfCancellationRequested():如果已请求取消,此方法会立即抛出 OperationCanceledException,这是标准做法。
  • Task.Delay(token):许多 .NET 异步 API(如 HttpClient.GetAsync)原生支持 CancellationToken,传入后可在等待期间响应取消。
  • 资源清理:建议在 finally 块或 using 语句中释放资源,确保即使任务被取消也能正确清理。

高级技巧:超时自动取消

有时我们希望任务在指定时间内未完成就自动取消。可以使用 CancellationTokenSource 的构造函数设置超时:

// 创建一个5秒后自动触发取消的 CTSvar cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));try{    await DoWorkAsync(cts.Token);}catch (OperationCanceledException){    Console.WriteLine("任务因超时被取消。");}

总结

通过合理使用 CancellationToken,你可以构建出响应迅速、资源安全的异步应用程序。无论是在桌面应用、Web API 还是后台服务中,C#任务取消 都是提升用户体验和系统健壮性的关键技术。

记住:取消是协作行为,不是强制中断。始终在你的异步方法中检查 CancellationToken,并善用 .NET 提供的内置支持(如 Task.DelayHttpClient 等)。

关键词回顾:CancellationTokenC#任务取消异步编程.NET取消令牌