Dans la documentation Microsoft, la méthode écoulée System.Timers.Timer
doit englober toutes les exceptions.System.Timers.Timer se bloque lors de l'affichage de l'exception
Le composant Timer intercepte et supprime toutes les exceptions levées par les gestionnaires d'événements pour l'événement Elapsed.
https://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Cependant lors de la souscription au moyen d'un procédé async void
une exception est produit qui bloque l'application. Voir le code ci-dessous:
class Program
{
static void Main(string[] args)
{
Timer timer = new Timer(100);
//timer.Elapsed += On_ElapsedSync; //A
//timer.Elapsed += On_ElapsedAsync; //B
timer.Elapsed += On_ElapsedAsyncVoid; //C
timer.Start();
Console.WriteLine("Running...");
Console.ReadLine();
}
private static void On_ElapsedSync(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Throwing...");
throw new Exception("My Exception");
}
private static void On_ElapsedAsync(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Throwing...");
Task.Run(() => throw new Exception("Async Exception"));
}
private static async void On_ElapsedAsyncVoid(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Throwing...");
await Task.Run(() => throw new Exception("Async Exception"));
}
}
Les lignes commentées A et B ne plantent pas l'application. La ligne a commenté C fait.
Pourquoi est-ce le cas?
Yuck, vous donnez l'impression que c'est une bonne fonctionnalité. Il se classe parmi les pires décisions .NET 1.0. Et bien sûr, cela ne fonctionne pas, le code qui déclenche l'événement est révolu depuis le début de la tâche. Donc, il ne peut rien attraper. Une méthode async-void est du code fire-and-forget. –
Je suis d'accord, ils devraient tous jeter. Mais j'ai été surpris quand l'attente asynchrone l'a fait. –
Les exceptions ['async void' ne peuvent pas être interceptées par des moyens normaux] (https://msdn.microsoft.com/fr-fr/magazine/jj991977.aspx). –