c# - example - Task.WhenAny y excepciones no observadas
task list c# (2)
Digamos que tengo tres tareas, a
, b
, y c
. Los tres están garantizados para lanzar una excepción en un tiempo aleatorio entre 1 y 5 segundos. Luego escribo el siguiente código:
await Task.WhenAny(a, b, c);
En última instancia, esto generará una excepción de las faltas de tarea primero. Ya que no hay ningún try...catch
aquí, esta excepción se propagará a otro lugar en mi código.
¿Qué sucede cuando las dos tareas restantes lanzan una excepción? ¿No son estas excepciones no observadas, que causarán la muerte de todo el proceso? ¿ WhenAny
significa que la única forma de usar WhenAny
es dentro de un bloque try...catch
, y luego observar las dos tareas restantes antes de continuar?
Seguimiento: me gustaría que la respuesta se aplique tanto a .NET 4.5 como a .NET 4.0 con el paquete de objetivos de Async (aunque claramente use TaskEx.WhenAny
en ese caso).
¿Qué sucede cuando las dos tareas restantes lanzan una excepción?
Esas Task
se completarán en un estado de falla.
¿No son estas excepciones no observadas, que causarán la muerte de todo el proceso?
Ya no.
En .NET 4.0, el TaskScheduler.UnobservedTaskException
Task
pasaría su excepción no observada a TaskScheduler.UnobservedTaskException
, que terminaría el proceso si no se manejaba.
En .NET 4.5, este comportamiento fue cambiado . Ahora, las excepciones no observadas se pasan a TaskScheduler.UnobservedTaskException
, pero luego se ignoran si no se manejan.
Sí, las excepciones de tareas restantes no se observan. Pre .NET 4.5 está obligado a observarlos (no está seguro de cómo está la situación en .NET 4.5, pero cambió).
Por lo general, me escribo a mí mismo un método auxiliar para tareas de fuego y olvido como estas:
public static void IgnoreUnobservedExceptions(this Task task)
{
if (task.IsCompleted)
{
if (task.IsFaulted)
{
var dummy = task.Exception;
}
return;
}
task.ContinueWith(t =>
{
var dummy = t.Exception;
}, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
}
Es posible que desee incluir el registro en aplicaciones de producción.