Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid nested AggregateException when using Task.ContinueWith?

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.

like image 411
Vagif Abilov Avatar asked Apr 14 '15 07:04

Vagif Abilov


1 Answers

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);
like image 177
Guillaume Avatar answered Sep 27 '22 22:09

Guillaume