使用Task.ContinueWith时如何避免嵌套的AggregateException? [英] How to avoid nested AggregateException when using Task.ContinueWith?
问题描述
我在.NET 4.5 C#组件中有一个异步方法:
公共异步任务< T> GetResultAsync()
{
return PerformOperationAsync();
}
如果PerformOperationAsync抛出异常,那么我可以在客户端捕获AggregateException ,将其解包并引发原始异常。
但是,如果我的代码稍微复杂一些:
公共异步任务< T> GetResultAsync()
{
return PerformOperationAsync()。ContinueWith(x =>
{
var result = x.Result;
return DoSomethingWithResult(result);
},cancelationToken);
}
...然后在发生异常的情况下,客户端捕获嵌套的AggregateException
应该避免这种行为,还是客户端必须期望嵌套了AggregateException并调用Flatten来解开所有级别,因此必须先对其进行展平。 ?而且,如果组件开发人员应避免这种行为,那么在ContinueWith场景中处理该行为的正确方法是什么?我有很多类似的情况,所以我试图找到最轻巧的方法来处理它们。
C#5异步/ await将帮助您处理连续性和适当的异常处理,同时简化代码。
公共异步任务< T> GetResultAsync()
{
var result = await PerformOperationAsync()。ConfigureAwait(false);
return DoSomethingWithResult(result);
}
您的方法已被标记为异步,是否有意?
要保持连续性,可以提供 TaskContinuationOptions
和 OnlyOnRanToCompletion
值:
PerformOperationAsync()。ContinueWith(x =>
{
var result = x.Result;
return DoSomethingWithResult(result);
},TaskContinuationOptions.OnlyOnRanToCompletion);
或使用侍者提出原始例外情况
PerformOperationAsync()。ContinueWith(x =>
{
var result = x.GetAwaiter()。GetResult();
返回DoSomethingWithResult (结果);
},cancelationToken);
I have an async method in a .NET 4.5 C# component:
public async Task<T> GetResultAsync()
{
return PerformOperationAsync();
}
If PerformOperationAsync throws an exception, then I can catch an AggregateException on a client side, unwrap it and get the original exception thrown.
However, if I have slightly more complicated code:
public async Task<T> GetResultAsync()
{
return PerformOperationAsync().ContinueWith(x =>
{
var result = x.Result;
return DoSomethingWithResult(result);
}, cancellationToken);
}
... then in case an exception occurs, the client catches a nested AggregateException, so it has to flatten it prior getting the original one.
Should this behavior be avoided or does client have to expect possibly nested AggregateException and call Flatten to unwrap all its levels? And if this behavior should be avoided by the component developer, then what's the right way to deal with it in ContinueWith scenario? I have plenty of similar situations, so I am trying to find the most lightweight method of handling them.
C#5 async/await will help you deal with continuations and proper exception handling while simplifying the code.
public async Task<T> GetResultAsync()
{
var result = await PerformOperationAsync().ConfigureAwait(false);
return DoSomethingWithResult(result);
}
Your method is already marked as async, is it intended ?
To keep the continuation you can provide a TaskContinuationOptions
with OnlyOnRanToCompletion
value :
PerformOperationAsync().ContinueWith(x =>
{
var result = x.Result;
return DoSomethingWithResult(result);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
or use the awaiter to raise the original exception
PerformOperationAsync().ContinueWith(x =>
{
var result = x.GetAwaiter().GetResult();
return DoSomethingWithResult(result);
}, cancellationToken);
这篇关于使用Task.ContinueWith时如何避免嵌套的AggregateException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!