Resumo : neste tutorial você aprenderá como tratar exceções geradas pela operação assíncrona executada pelos Task
objetos.
Introdução à AggregateException
Em geral, quando Task
encontra uma exceção, ele a propaga para o thread de chamada. Se a Task
contiver tarefas aninhadas, quaisquer operações assíncronas executadas nessas tarefas também poderão resultar no lançamento de várias exceções.
Para propagar todas as exceções para o thread de chamada, Task
envolva-as em um
objeto.AggregateException
O
objeto possui a AggregateException
InnerExceptions
propriedade que contém todas as exceções originais. A InnerExceptions
é uma coleção somente leitura das Exception
instâncias.
Para tratar essas exceções, você pode enumerá-las através da InnerExceptions
propriedade do AggregateException
objeto usando um foreach
loop.
Alternativamente, você pode lidar com as exceções originais usando o AggregateException.Handle
método:
public void Handle (Func<Exception,bool> predicate);
Linguagem de código: PHP ( php )
É importante observar que agrupará Task
todas as exceções que ocorrerem em um AggregationException
objeto, mesmo que uma única exceção seja gerada.
Exemplo de tratamento de AggregateException
O programa a seguir ilustra como lidar com exceções em uma operação assíncrona executada por uma tarefa.
decimal Divide(decimal a, decimal b)
{
Thread.Sleep(1000);
return a / b;
}
try
{
var task = Task.Run(() => Divide(10, 0));
var result = task.Result;
}
catch (AggregateException ae)
{
ae.Flatten().Handle(e =>
{
if (e is DivideByZeroException)
{
Console.WriteLine(e.Message);
return true;
}
else
{
throw e;
}
});
}
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, defina um método Divide()
que receba dois números decimais e retorne o resultado da divisão deles após um atraso de um segundo:
decimal Divide(decimal a, decimal b)
{
Thread.Sleep(1000);
return a / b;
}
Linguagem de código: C# ( cs )
Segundo, use o
método para executar o Task.Run
()Divide()
método de forma assíncrona em um thread separado. Como usamos os argumentos 10 e 0, o Divide()
método lançará uma DivideByZeroException
exceção:
var task = Task.Run(() => Divide(10, 0));
Linguagem de código: C# ( cs )
Terceiro, use o bloco try…catch para capturar quaisquer exceções lançadas pelo método. Como a operação assíncrona lança um AggregateException
, nós o capturamos e tratamos no catch
bloco.
No manipulador de exceções, usamos o Handle()
método da AggregateException
classe para tratar cada exceção interna.
Se a exceção for DivideByZeroException
, o programa enviará a mensagem de erro para o console. Caso contrário, ele relançará a mesma exceção.
Ao executar o programa, você verá a seguinte saída:
Attempted to divide by zero.
Linguagem de código: C# ( cs )
Resumo
- Use o
try...catch
para capturar oAggregateException
lançado pela operação assíncrona executada por umTask
. - Use o
AggregateException.Handle()
método para lidar com exceções.