首页
看点啥
插画图片
首页 科技看点 .NET中TaskCompletionSource的用法小结实用指南

.NET中TaskCompletionSource的用法小结实用指南

2026-08-27 0

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“.NET中TaskCompletionSource的用法小结”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

TaskCompletionSource 是 .NET 中用来控制和管理异步任务 (Task) 的类,广泛用来在异步编程中手动控制任务的完成。它通常与 asyncawait 配合采用,但它本身是用来新建、设置或操作任务的结果的。

TaskCompletionSource的基本概念

实际处理时,在标准的异步编程里,你会看到异步方法得到一个 TaskTask 对象,它代表着一个尚未完成的操作。而 TaskCompletionSource 类允许你手动设置这些任务的状态,比如让任务完成、失败或取消。

TaskCompletionSource类的构造与采用

  1. 构造函数

    • 结合项目来看,TaskCompletionSource():新建一个新的 TaskCompletionSource 实例。
    • 理解这一步时,TaskCompletionSource(CancellationToken cancellationToken):带有取消标记的构造函数。

    理解这一步时,TaskCompletionSource 本身同时不直接执行任务,它仅提供了一些方法来控制任务的状态。

  2. 关键属性

    • Task:TaskCompletionSource 类有一个公开的属性 Task,它得到一个 Task 实例,表示这个任务的状态。你能够借助这个属性来跟踪任务的状态,同时借助 await 来等待其完成。
    • Task.IsCompleted:判断任务是否完成。
    • Task.IsFaulted:判断任务是否因错误而失败。
    • Task.IsCanceled:判断任务是否被取消。
  3. 关键方法

    • 结合项目来看,SetResult(T result):完成任务同时提供结果。如果任务已完成(无论是成功、失败还是取消),这会引发异常。
    • 结合项目来看,SetException(IEnumerable exceptions):让任务以失败的状态完成,同时报告异常。
    • 从实现思路看,SetException(Exception exception):让任务以失败的状态完成,同时报告单个异常。
    • SetCanceled():将任务标记为已取消状态。
    • 结合项目来看,TrySetResult(T result):类似于 SetResult,但它不会抛出异常,如果任务已经完成(无论是成功、失败还是取消),会得到 false。
    • 落到代码里,TrySetException(IEnumerable exceptions):与 SetException 类似,但如果任务已经完成,则得到 false。
    • 理解这一步时,TrySetException(Exception exception):类似于 SetException,但如果任务已完成,则得到 false。
    • 结合项目来看,TrySetCanceled():与 SetCanceled 类似,但如果任务已经完成,则得到 false。
  4. 常用场景
    在这个场景下,TaskCompletionSource 常用来那些你无法直接控制任务完成的场景,或者在一些复杂的异步控制流中。以下是一些常用的采用场景:

    • 异步回调转换:如果你有一个基于回调的异步API,但你想采用 Task 来控制它的执行,能够采用 TaskCompletionSource。比如,假设你在处理一个异步的文件读写操作,同时且你想将其转换为 Task:

      public Task ReadFileAsync(string path)
      {
          var tcs = new TaskCompletionSource();

          // 模拟异步操作的回调
          File.ReadAllTextAsync(path).ContinueWith(task =>
          {
              if (task.IsFaulted)
              {
                  tcs.SetException(task.Exception); // 设置异常
              }
              else if (task.IsCanceled)
              {
                  tcs.SetCanceled(); // 设置取消
              }
              else
              {
                  tcs.SetResult(task.Result); // 设置结果
              }
          });

          return tcs.Task;
      }
    • 手动控制异步任务的完成:有时在异步操作中,任务的完成是由某个外部事件触发的。你能够采用 TaskCompletionSource 来手动完成任务。比如,基于某个标志位或者外部事件来触发任务的完成:

      public Task WaitForExternalEventAsync()
      {
          var tcs = new TaskCompletionSource();

          // 假设有一个外部事件
          ExternalEventTriggered += (sender, e) =>
          {
              tcs.SetResult(null); // 当事件触发时,设置任务完成
          };

          return tcs.Task;
      }
    • 取消兼容的异步操作:你能够将 TaskCompletionSourceCancellationToken 配合采用,在任务中兼容取消。比如:

      public Task LongRunningTask(CancellationToken cancellationToken)
      {
          var tcs = new TaskCompletionSource();

          cancellationToken.Register(() => tcs.SetCanceled()); // 任务取消时标记为已取消

          Task.Run(() =>
          {
              try
              {
                  // 模拟长时间运行的操作
                  Thread.Sleep(5000);

                  if (!cancellationToken.IsCancellationRequested)
                  {
                      tcs.SetResult("Task Completed");
                  }
              }
              catch (Exception ex)
              {
                  tcs.SetException(ex);
              }
          });

          return tcs.Task;
      }
    • 例子:采用TaskCompletionSource完成一个异步任务

      public Task GetDataAsync()
      {
          var tcs = new TaskCompletionSource();

          // 模拟异步操作
          Task.Run(() =>
          {
              try
              {
                  // 假设在这里获取数据
                  string data = "Hello, world!";
                  tcs.SetResult(data); // 操作成功,设置结果
              }
              catch (Exception ex)
              {
                  tcs.SetException(ex); // 操作失败,设置异常
              }
          });

          return tcs.Task;
      }

      线程安全

      从实现思路看,TaskCompletionSource 是线程安全的,能够在多个线程中安全地调用其方法,比如 SetResult、SetException 等。不过,你只应该在任务完成后调用一次这些方法,否则会引发 InvalidOperationException。

      总结

      从实现思路看,TaskCompletionSource 是一个很强大的工具,允许开发者以更加灵活的方式控制和管理异步任务。它让你能够将基于回调的异步编程模型转化为更加直观和易于管理的 Task 模型,同时还提供了手动控制任务状态(完成、失败或取消)的能力。在处理复杂异步控制流时,TaskCompletionSource 是很有用的。

      到此这篇关于.NET中TaskCompletionSource的用法小结的文章就介绍到这了,更多相关.NET TaskCompletionSource内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!

      您可能感兴趣的文章:
      • .NET中的async和await关键字采用及Task异步调用实例
      • .net4.5采用async和await异步编程实例
      • asp.net+jquery.form实现图片异步上传的方法(附jquery.form.js下载)
      • 在.NET Core中采用异步编程的方法步骤
      • asp.net下实现兼容文件分块多点异步上传的 Web Services
      • jquery异步调用页面后台方法‏(asp.net)
      • .net的socket异步通讯示例分享
      • asp.net 采用js分页实现异步加载数据
      • .NET中基于事件的异步模式-EAP
      • 高效的.Net UDP异步编程实现分析
      喜欢(0)