2012-11-07 8 views
5

Ich frage mich, wie ich in C# Ausnahmen von asynchronen Methoden abfangen sollte, die über das Schlüsselwort await abgewartet werden. Betrachten Sie zum Beispiel das folgende kleine Konsolenprogramm, das vor allem eine Methode namens AwaitSync enthält. AwaitSync ruft TestAsync auf, die einen Task zurückgibt, der bei Ausführung eine Ausnahme auslöst. Ich versuche, die Ausnahme in AwaitAsync, zu fangen, aber es geht unbehandelt.Wie erhalte ich in C# eine Ausnahme von einer asynchronen Methode, die erwartet wird?

class Program 
{ 
    static void Main(string[] args) 
    { 
     AwaitAsync(); 
     Console.ReadKey(); 
    } 

    static async Task AwaitAsync() 
    { 
     try 
     { 
      await TestAsync(); 
     } 
     catch (Exception) 
     { 
      Console.WriteLine("Exception caught"); 
     } 
    } 

    static Task TestAsync() 
    { 
     return Task.Factory.StartNew(() => { throw new Exception("Test"); }); 
    } 
} 

Wie soll ich über den Fang, die Ausnahme von der Aufgabe von TestAsync zurück gehen soll? Während dieses Beispiel ein Konsolenprogramm ist, liegt mein Problem im wirklichen Leben im Kontext von ASP.NET MVC/Web API.

EDIT: aus Schaltet die Ausnahme gefangen wird immer aus technischen Gründen habe ich einfach nicht die ‚Exception gefangen‘ Meldung fest, bevor das Terminal geschlossen. In jedem Fall war Jon Skeets Antwort sehr wertvoll für mein Verständnis von await und Exception Handling.

+1

Sie sagen, dass das nicht funktioniert? – jishi

+2

Wenn ich Ihren Code ausführen, sehe ich "Ausnahme gefangen". – spender

+0

Es wird nicht für mich gefangen. Ich werde es noch einmal überprüfen. – aknuds1

Antwort

10

Der Code für die Expression await erzeugte GetResult() auf der mit dem von TestAsync zurück Task assoziiert TaskAwaiter nennen.

GetResult wird feststellen, dass die Aufgabe fehlerhaft ist, holt die erste Ausnahme von den AggregateException innerhalb der Aufgabe, und das werfen.

Das Nettoergebnis ist, dass Ihr catch-Block wird die Ausnahme in der Aufgabe geworfen fangen - aber wenn Sie eine Aufgabe warten, die mehrere Ausnahmen hat, werden Sie nur die erste sehen, wenn Sie spezielle Aktionen (es gibt verschiedene Ansätze dazu).

Da Sie behaupten, dass die Ausnahme tatsächlich unbehandelt ist, scheint es, dass etwas in Ihrem Code anders ist als was Sie zeigen - wie der Code, den Sie gegeben haben, sollte sicherlich funktionieren, und tut es für mich.

+0

Danke, wird nach dem Mittagessen ausgearbeitet. – aknuds1

+0

Es stellt sich heraus, dass die Ausnahme tatsächlich abgefangen wird, aber die Bestätigungsnachricht wird nicht auf die Konsole geschrieben, bevor ich eine Taste drücke, um das Programm zu beenden. Daher habe ich nicht bemerkt, dass die Nachricht zuerst gedruckt wurde. Vermutung Asynchronität braucht etwas gewöhnungsbedürftig :) – aknuds1

+0

Vielen Dank übrigens für Ihre Erklärung, wie Ausnahmen behandelt werden mit warten, sehr nützlich für mein Verständnis. – aknuds1

Verwandte Themen