我在.NET 4.5 C#组件中有一个异步方法:

public async Task<T> GetResultAsync()
{
    return PerformOperationAsync();
}

如果PerformOperationAsync抛出异常,那么我可以在客户端捕获AggregateException,将其解包并获取原始异常。

但是,如果我的代码稍微复杂一些:
public async Task<T> GetResultAsync()
{
    return PerformOperationAsync().ContinueWith(x =>
    {
        var result = x.Result;
        return DoSomethingWithResult(result);
    }, cancellationToken);
}

...如果发生异常,客户端将捕获嵌套的AggregateException,因此必须在获取原始异常之前对其进行展平。

是应该避免这种行为,还是客户端必须期望可能嵌套的AggregateException并调用Flatten来解开其所有级别?而且,如果组件开发人员应避免这种行为,那么在ContinueWith场景中处理该行为的正确方法是什么?我有很多类似的情况,因此我试图找到最轻巧的方法来处理它们。

最佳答案

C#5 async/await将帮助您处理延续和适当的异常处理,同时简化代码。

public async Task<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);

或使用侍者提出原始异常(exception)
PerformOperationAsync().ContinueWith(x =>
{
    var result = x.GetAwaiter().GetResult();
    return DoSomethingWithResult(result);
}, cancellationToken);

关于c# - 使用Task.ContinueWith时如何避免嵌套的AggregateException?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29621079/

10-10 17:15