将任务包装为任务<TResult>的最佳方法是什么?

Cha*_*ion 7 c# task-parallel-library async-await

我正在编写一些异步辅助方法,我有API来支持TaskTask<T>.为了重用代码,我希望Task基于-Based的API将给定的任务包装成一个Task<T>并且只需调用Task<T>API.

我可以这样做的一种方法是:

private static async Task<bool> Convert(this Task @this)
{
    await @this.ConfigureAwait(false);
    return false;
}
Run Code Online (Sandbox Code Playgroud)

但是,我想知道:有没有更好/内置的方法来做到这一点?

Ser*_*rvy 6

没有现成的Task方法可以做到这一点,没有.你的方法很好,很可能就像你能得到的一样简单.

使用任何其他方法实现适当的错误传播/取消语义看似很难.


nos*_*tio 5

更新后,以下传播异常和取消:

public static class TaskExt
{
    public static Task<Empty> AsGeneric(this Task @this)
    {
        return @this.IsCompleted ?
            CompletedAsGeneric(@this) :
            @this.ContinueWith<Task<Empty>>(CompletedAsGeneric, 
                TaskContinuationOptions.ExecuteSynchronously).Unwrap();
    }

    static Task<Empty> CompletedAsGeneric(Task completedTask)
    {
        try
        {
            if (completedTask.Status != TaskStatus.RanToCompletion)
                // propagate exceptions
                completedTask.GetAwaiter().GetResult();

            // return completed task
            return Task.FromResult(Empty.Value);
        }
        catch (OperationCanceledException ex)
        {
            // propagate cancellation
            if (completedTask.IsCanceled)
                // return cancelled task
                return new Task<Empty>(() => Empty.Value, ex.CancellationToken);
            throw;
        }
    }
}

public struct Empty
{
    public static readonly Empty Value = default(Empty);
}
Run Code Online (Sandbox Code Playgroud)

  • 他的取消不会作为取消传播; 取消的任务变成了故障任务. (2认同)