有没有一种简单的方法可以返回带有异常的任务

本文关键字:返回 任务 异常 方法 一种 有没有 简单 | 更新日期: 2023-09-27 17:52:46

我的理解是return Task.FromResult(foo)是以下的简单简写:

var tcs = new TaskCompletionSource<TFoo>();
tcs.SetResult(foo);
return tcs.Task;

返回异常状态的任务是否有等效项?

var tcs = new TaskCompletionSource<TFoo>();
tcs.SetException(new NotSupportedException()); // or whatever is appropriate
return tcs.Task;

我没有看到像Task.FromException这样的东西. 还是只抛出异常而不返回任务更合适?

有没有一种简单的方法可以返回带有异常的任务

从 .NET 4.6 开始,BCL 中有一个Task.FromException方法。

还有Task.FromCanceled.

我的理解是返回 Task.FromResult(foo( 是一个简单的 简写...[ TaskCompletionSource.SetResult ]。

实际上,Task.FromResult不使用TaskCompletionSource,它的实现比这简单得多。

返回异常状态的任务是否有等效项?

我认为TaskCompletionSource将是最好的选择。你也可以做这样的事情:

static Task FromExAsync(Exception ex) 
{
    var task = new Task(() => { throw ex; });
    task.RunSynchronously();
    return task;
}

异常不会传播到返回的task之外,直到通过await tasktask.Wait()观察到,这应该是一个期望的行为。

请注意,如果传递给 FromExAsync 的异常是活动异常(即已经抛出并在其他地方捕获(,则像这样重新抛出它将丢失存储在异常中的当前堆栈跟踪和 Watson 存储桶信息。有两种处理方法:

  • AggregateException 包装异常。这将使原始异常可用作AggregateException.InnerException

static Task FromExAsync(Exception ex) 
{
    var task = new Task(() => { throw new AggregateException(ex); });
    task.RunSynchronously();
    return task;
}
  • 使用 ExceptionDispatchInfo.Capture 来传递活动异常的状态:

static Task FromExAsync(Exception ex) 
{
    var ei = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex);
    var task = new Task(() => { ei.Throw(); });
    task.RunSynchronously();
    return task;
}

最后,也许最简单但最糟糕的选择(由于状态机的开销和编译器警告(是从async方法中抛出:

static async Task FromExAsync(Exception ex)
{
    throw ex;
}