2017-09-12 3 views
0

Aus der Microsoft-Dokumentation sollte die System.Timers.Timer verstrichene Methode alle Ausnahmen verschlingen.System.Timers.Timer stürzt bei Ausnahme ab

Die Komponente Timer fängt alle Ausnahmen ab, die von Ereignishandlern für das Ereignis Elapsed ausgelöst werden, und unterdrückt sie.

https://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

jedoch, wenn eine Ausnahme erzeugt wird, unter Verwendung eines Verfahrens async void Zeichnung, die die Anwendung abstürzt. Siehe unten stehenden Code:

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")); 
    } 
} 

Die Zeilen kommentiert A und B stürzen die Anwendung nicht ab. Die Zeile kommentierte C.

Warum ist das der Fall?

+2

Yuck, Sie machen es klingt, als ob es ein gutes Feature ist. Es zählt zu den schlechtesten .NET 1.0-Entscheidungen. Und sicher, funktioniert nicht, der Code, der das Ereignis auslöst, ist bis zum Abschluss der Aufgabe längst verschwunden. Es kann also nichts fangen. Eine Async-Void-Methode ist ein Code für den Code "Fire-and-Forget". –

+0

Ich stimme zu, sie sollten alle werfen. Aber ich war überrascht, als der Async auf mich wartete. –

+0

['async void' Ausnahmen können nicht mit normalen Mitteln abgefangen werden] (https://msdn.microsoft.com/en-us/magazine/jj991977.aspx). –

Antwort

3

The link you provided Zustände:

Die Timer-Komponente Fänge und unterdrückt alle von Event-Handler für das Elapsed-Ereignis ausgelöste Ausnahmen. Dieses Verhalten unterliegt in zukünftigen Versionen von .NET Framework der Änderung . Beachten Sie jedoch, dass dies nicht für Event-Handler gilt, die asynchron ausgeführt werden, und den await-Operator (in C#) oder den Await-Operator (in Visual Basic) enthalten. Ausnahmen, die in diesen Ereignisprozeduren ausgelöst werden, werden an den aufrufenden Thread zurückgegeben, wie im folgenden Beispiel veranschaulicht. Weitere Informationen zu Ausnahmen, die in asynchronen Methoden ausgelöst werden, finden Sie unter Ausnahmebehandlung (Task Parallel Library).

Da Sie await dann der letzte Teil der Dokumentation verwenden gilt:

Ausnahmen in dieser Event-Handler geworfen werden wieder an den aufrufenden Thread propagiert, wie das folgende Beispiel zeigt.

Verwandte Themen