You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取取消Task的CancellationToken?附Task转TaskCompletionSource代码

把Task结果同步到TaskCompletionSource的标准实现细节

咱们先看完整的实现代码:

TaskCompletionSource<int> tcs = ...; 
Task<int> task = ...; 
task.ContinueWith(t => { 
    if (t.IsCanceled) 
        tcs.TrySetCanceled(new TaskCanceledException(task).CancellationToken); 
    else if (t.IsFaulted) 
        tcs.TrySetException(task.Exception.InnerExceptions); 
    else 
        tcs.TrySetResult(task.Result); 
});

这段代码是异步编程里桥接普通Task和TaskCompletionSource的标准操作,我来拆解下关键细节,尤其是你提到的取消令牌那部分:

  • 核心逻辑:通过ContinueWith注册原Task的完成回调,把原任务的「取消/失败/成功」三种状态,同步到TaskCompletionSource对应的状态上,让外部可以通过tcs.Task获取和原任务一致的异步结果。
  • 取消状态的特殊处理:这里特意创建TaskCanceledException(task)再提取它的CancellationToken传入TrySetCanceled。这么做是因为原Task的CancellationToken可能已经被销毁、或者无法直接访问(比如原任务是第三方库返回的),通过这个异常对象可以拿到和原取消操作绑定的有效令牌。如果直接调用无参的TrySetCanceled(),默认会传入一个空的取消令牌,后续监听tcs.Task的取消状态时,就没法拿到触发取消的原始令牌上下文,会影响错误处理的准确性。
  • 异常状态处理:用task.Exception.InnerExceptions而非直接传task.Exception,是因为Task的异常会被包装在AggregateException里,传入内部异常列表能让tcs抛出的异常更贴合原任务的错误场景,避免额外的聚合包装层。
  • 成功状态处理:直接把原Task的结果同步给tcs即可,逻辑相对简单。

内容的提问来源于stack exchange,提问作者Cory Nelson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:04:46