使用Task.ContinueWith时如何避免嵌套的AggregateException? [英] How to avoid nested AggregateException when using Task.ContinueWith?

查看:57
本文介绍了使用Task.ContinueWith时如何避免嵌套的AggregateException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆