C# TaskCompletionSource

TaskCompletionSource<T> 的核心作用是:手动控制一个 Task 的完成状态 。它适合把回调、事件、外部信号转成 await 能用的 Task。

基本用法

csharp 复制代码
var tcs = new TaskCompletionSource<string>(
    TaskCreationOptions.RunContinuationsAsynchronously);

// 消费方
string result = await tcs.Task;

// 生产方在回调/事件里完成
tcs.TrySetResult("ok");

常用方法

方法 作用
tcs.Task 返回等待方使用的 Task
TrySetResult(v) 标记成功,返回 bool,重复调用不抛异常
TrySetException(ex) 标记失败
TrySetCanceled() 标记取消
SetResult(v) 强制完成,重复调用会抛 InvalidOperationException

生产环境建议统一用 TrySet*,避免回调多次触发时崩溃。

桥接事件/回调

csharp 复制代码
public Task<string> WaitForMessageAsync()
{
    var tcs = new TaskCompletionSource<string>(
        TaskCreationOptions.RunContinuationsAsynchronously);

    void Handler(object? s, string msg)
    {
        _messageSource.Received -= Handler;
        tcs.TrySetResult(msg);
    }

    _messageSource.Received += Handler;
    return tcs.Task;
}

加超时

csharp 复制代码
var tcs = new TaskCompletionSource<string>(
    TaskCreationOptions.RunContinuationsAsynchronously);

var timeout = Task.Delay(3000);
var completed = await Task.WhenAny(tcs.Task, timeout);

if (completed == timeout)
    throw new TimeoutException();

return await tcs.Task;

注意:TCS 超时只是让等待方不再等,底层操作不一定真的被取消。

关键点

  • 构造时加 RunContinuationsAsynchronously,防止续体在设置结果的线程上同步执行,减少死锁风险。
  • TCS 只能完成一次,状态一旦变成 Completed / Faulted / Canceled 就不能再改。
  • 需要重复使用时,每次创建新实例,不要复用已完成的 TCS。
相关推荐
当战神遇到编程1 小时前
Java 基础入门(七):递归详解——执行原理、方法调用栈与经典练习
java
eggwyw1 小时前
C++深入浅出探索数据结构的原理
开发语言·c++
eggwyw1 小时前
C++深入浅出讲解希尔排序算法的实现
开发语言·c++
starzy19901 小时前
Scala Array操作:从定长数组到ArrayBuffer的完整指南
开发语言·后端·scala
若亦_1 小时前
排序>>交换排序
java·数据结构·算法
Wang's Blog1 小时前
MongoDB 地理位置上报实战:从接口设计到覆盖写入的完整实现
java·交友
读书札记20221 小时前
Qt UTF-8和UTF-8(BOM)
开发语言·qt
ShineWinsu1 小时前
对于Qt:QProgressBar常见属性的解析
开发语言·c++·qt·进度条·gui·定时器·qprogressbar
fanruitian1 小时前
python 机器学习 交叉验证train_test_split 网格搜索GridSearchCV
开发语言·python·机器学习