Why is it not possible to capture exceptions triggered by async void?

Asked

Viewed 157 times

2

Why it is not possible to capture exceptions triggered by non-recurring asynchronous methods Task?

public async void calcularPrecos()
{
    var tabelaPreco = await getTabelaPreco();
    /* Blá, blá, blá... */
}

public void iniciarCalculos()
{
    try
    {
        calcularPrecos();
        /* Blá, blá, blá... */
    }
    catch (WebException e)
    {
        /* A exceção é disparada mas não é capturada neste ponto. =( */
    }
}

The method getTabelaPreco() requires internet connection, otherwise it triggers an exception of type WebException, but I cannot capture such an exception in try-catch inside iniciarCalculos().

  • Maybe creating a [mcve] will make it easier to identify the problem.

  • Dear @bigown, this is a real example, I thought the consequent lines would not add in solving the problem.

  • 1

    If it were real it would give to compile it. I continue with my suggestion to do in the way indicated there. And it is not to put all the code, only the minimum to check the condition of the error, at the moment can not be sure what this code does and why the exception is not captured, it can be up because it was not launched.

  • 1

    Friend, your method iniciarCalculos it is not asynchronous, it will not work right (probably also that this is the problem). Use reserved words async and await in this method just as you did in the calcularPrecos.

  • Related link https://github.com/dotnet/roslyn/issues/13897

1 answer

6


It is not captured because the method calcularPrecos() returns nothing(void).

For the exception to be propagated it is necessary that it returns Task or Task<T>.

When an exception is launched from an asynchronous task that returns Task or Task <T>, it is captured and placed in the object Task returned.

In the case of methods that return void there is no object Task, therefore, any exceptions launched cannot be captured (except by observing the Appdomain.Unhandledexception Event).

Note that the exception is only released when the task is executed. Try/catch will catch the exception only then.

In his example(1), even if the method calcularPrecos() return a Task, the block try/catch would not capture the exception because, when it occurs, the execution will have already left that block.

So to call the method you have to use await calcularPrecos(); or calcularPrecos().Wait();

See what the documentation says about Async Return Types.

(1) See the commenting of Gabriel Katakura.

  • 1

    Don’t just put Task in calcularPrecos, in the method call calcularPrecos it is also necessary to carry out a Wait() if the method making the call (sorry for the odd term) is a synchronous method. Here is the solution: https://dotnetfiddle.net/LDQpuG

  • @Gabrielkatakura Thank you for the reminder, I edited the reply.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.