写点什么

探索 C#中 Task 与 CancellationTokenSource 的协同艺术

作者:代码忍者
  • 2024-12-21
    江西
  • 本文字数:1766 字

    阅读完需:约 6 分钟

在现代 C#编程中,异步编程模式已经成为处理并发任务的重要工具。Task 类和 CancellationTokenSource 类的结合使用,为开发者提供了一种灵活且强大的方式来管理和取消异步操作。本文将深入探讨 Task 与 CancellationTokenSource 的协同艺术,展示它们如何在实现高效、可控的异步操作中发挥关键作用。


一、Task:异步编程的核心 Task 类是.NET 中用于表示异步操作的对象。通过 Task,你可以轻松地在后台线程上执行耗时操作,而不会阻塞主线程。Task 的灵活性在于它既可以表示已启动的操作,也可以表示即将启动的操作,还可以表示多个子任务的组合。


csharpTask task = Task.Run(() => {// 耗时操作 Thread.Sleep(5000);Console.WriteLine("任务完成");});


task.Wait(); // 等待任务完成二、CancellationTokenSource:取消异步操作的利器 CancellationTokenSource 是用于请求取消操作的令牌源。它生成一个 CancellationToken,该令牌可以被传递给需要取消支持的操作。当 CancellationTokenSource 请求取消时,关联的 CancellationToken 将触发取消操作,允许正在执行的任务检查并响应取消请求。


csharpCancellationTokenSource cts = new CancellationTokenSource();CancellationToken token = cts.Token;


Task task = Task.Run(() => {for (int i = 0; i < 10; i++){if (token.IsCancellationRequested){Console.WriteLine("任务已取消");token.ThrowIfCancellationRequested();}Thread.Sleep(1000);Console.WriteLine($"正在执行任务 {i + 1}");}Console.WriteLine("任务完成");}, token); // 将 token 传递给 Task


// 延迟一段时间后取消任务 Thread.Sleep(3000);cts.Cancel();


try{task.Wait(); // 等待任务完成或抛出异常}catch (OperationCanceledException){Console.WriteLine("捕获到取消异常");}三、Task 与 CancellationTokenSource 的协同艺术将 Task 与 CancellationTokenSource 结合使用,可以实现复杂的异步操作管理。例如,你可以启动一个长时间运行的任务,并在必要时取消它,同时确保任务能够优雅地处理取消请求,释放资源并清理状态。


示例:下载文件并支持取消假设我们需要下载一个文件,并允许用户在下载过程中取消操作。我们可以使用 Task 来执行下载操作,并使用 CancellationTokenSource 来管理取消请求。


csharpusing System;using System.IO;using System.Net.Http;using System.Threading;using System.Threading.Tasks;


class Program{static async Task DownloadFileAsync(string url, string filePath, CancellationToken token){using (HttpClient client = new HttpClient())using (var response = await client.GetAsync(url, token))using (var stream = await response.Content.ReadAsStreamAsync())using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)){await stream.CopyToAsync(fileStream, 81920, token); // 缓冲区大小 80KB}}


static async Task Main(string[] args){    string url = "https://example.com/largefile.zip";    string filePath = "largefile.zip";
CancellationTokenSource cts = new CancellationTokenSource();
Task downloadTask = DownloadFileAsync(url, filePath, cts.Token);
Console.WriteLine("按任意键取消下载..."); Console.ReadKey();
cts.Cancel();
try { await downloadTask; } catch (OperationCanceledException) { Console.WriteLine("下载已取消"); // 清理已下载的部分文件 if (File.Exists(filePath)) { File.Delete(filePath); Console.WriteLine("已删除部分下载文件"); } }}
复制代码


}在这个示例中,DownloadFileAsync 方法使用 HttpClient 下载文件,并通过 CopyToAsync 方法将响应流复制到文件流中。CancellationToken 被传递给所有支持取消的异步方法,以确保在取消请求到达时能够立即响应。


四、总结 Task 与 CancellationTokenSource 的结合使用,为 C#异步编程提供了强大的功能和灵活性。通过合理管理任务的生命周期和取消请求,你可以构建更加健壮、可控和响应迅速的异步应用程序。无论是处理网络请求、文件 I/O 还是复杂的计算任务,Task 与 CancellationTokenSource 都将成为你不可或缺的工具。

用户头像

代码忍者

关注

还未添加个人签名 2024-07-23 加入

还未添加个人简介

评论

发布
暂无评论
探索C#中Task与CancellationTokenSource的协同艺术_代码忍者_InfoQ写作社区