我的理解是返回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的东西.或者更恰当的是抛出异常而不返回任务?
解决方法
My understanding is that return Task.FromResult(foo) is a simple
shorthand for… [TaskCompletionSource.SetResult
].
实际上,Task.FromResult不使用TaskCompletionSource,所以its implementation比这简单得多.
Is there some equivalent for a task that returns an exception state?
我估计TaskCompletionSource将是最好的选择.你也可以这样做:
static Task FromExAsync(Exception ex) { var task = new Task(() => { throw ex; }); task.RunSynchronously(); return task; }
异常将不会在返回的任务之外传播,直到通过等待任务或task.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; }
最后,也许最简单但最糟糕的选择(由于overhead of the state machine和编译器警告)是从异步方法抛出的:
static async Task FromExAsync(Exception ex) { throw ex; }