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

如何不使用异步状态机将Task包装为Task<TResult>?

非异步方式将Task包装为Task的无错误实现

可以通过TaskCompletionSource<T>实现完全符合要求的非异步包装方案,无需生成异步状态机,同时严格保留原Task的核心属性:

Task<T> ConvertToTaskOfT<T>(Task task, T result)
{
    if (task == null)
        throw new ArgumentNullException(nameof(task));

    var tcs = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);

    // 先处理任务已完成的场景,避免多余的延续注册
    switch (task.Status)
    {
        case TaskStatus.RanToCompletion:
            tcs.SetResult(result);
            break;
        case TaskStatus.Faulted:
            tcs.SetException(task.Exception.InnerExceptions);
            break;
        case TaskStatus.Canceled:
            tcs.SetCanceled();
            break;
        default:
            // 任务未完成时,注册延续同步状态
            task.ContinueWith(t =>
            {
                switch (t.Status)
                {
                    case TaskStatus.RanToCompletion:
                        tcs.SetResult(result);
                        break;
                    case TaskStatus.Faulted:
                        tcs.SetException(t.Exception.InnerExceptions);
                        break;
                    case TaskStatus.Canceled:
                        tcs.SetCanceled();
                        break;
                }
            }, TaskContinuationOptions.ExecuteSynchronously);
            break;
    }

    return tcs.Task;
}

符合要求的验证说明

  • 状态完全同步:无论是原Task已完成还是未完成,都会直接将其状态同步到TaskCompletionSource生成的Task<T>中,返回对象的Status属性与原Task完全一致。
  • Exception属性一致:原Task故障时,直接传递其Exception.InnerExceptions给SetException方法,确保返回的Task<T>的Exception属性与原Task完全相同。
  • 无阻塞异步执行:通过Task.ContinueWith注册的延续操作会在原Task完成时异步触发,不会阻塞当前线程;TaskCreationOptions.RunContinuationsAsynchronously参数确保后续绑定到返回Task<T>的延续也会异步执行,彻底避免阻塞。

内容的提问来源于stack exchange,提问作者Ivan Petrov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:22:32