2012-11-07 10 views
5

Zasadniczo zastanawiam się, jak powinienem, w języku C#, przechwytywać wyjątki od metod asynchronicznych, które czekają za pośrednictwem słowa kluczowego await. Rozważmy na przykład następujący mały program konsoli, który przede wszystkim zawiera metodę o nazwie AwaitSync. AwaitSync dzwoni TestAsync, która zwraca zadanie, które po wykonaniu zgłasza wyjątek. Próbuję złapać wyjątek w AwaitAsync, , ale nieobsługiwany.Jak złapać w C# wyjątek od metody asynchronicznej, który jest oczekiwany?

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

Jak mam się do tego zabrać połowu wyjątek od zadania zwracany przez TestAsync? Podczas gdy ten przykład jest programem konsolowym, mój prawdziwy problem jest związany z ASP.NET MVC/Web API.

EDIT: Okazuje się, że wyjątek jest złapanym przyczyn technicznych po prostu nie zauważył komunikat „wyjątek” złapany przed terminal zamknięty. W każdym razie odpowiedź Jona Skeeta była bardzo cenna dla mojej wiedzy o obsłudze wyjątków.

+1

Czy mówisz, że to nie działa? – jishi

+2

Po uruchomieniu kodu widzę "Wyłapany wyjątek". – spender

+0

To nie mnie złapie. Sprawdzę ponownie. – aknuds1

Odpowiedz

10

Kod generowany dla ekspresji await wezwie GetResult() na TaskAwaiter związanego z Task zwróconej przez TestAsync.

GetResult zauważy, że zadanie jest nic zarzucić, pobrać pierwszy wyjątek od AggregateException w ramach zadania, i że rzucać.

Wynik netto jest to, że blok catch złapie wyjątek rzucony w swoim zadaniu - ale jeśli czekają zadania, które ma wielu wyjątki, zobaczysz tylko pierwszy z nich, chyba że podjęcie specjalnych działań (są różne podejścia do tego).

Ponieważ twierdzisz, że wyjątek w rzeczywistości nie jest obsługiwany, wydaje się, że w Twoim kodzie jest coś innego niż to, co pokazujesz - kod, który podałeś, powinien z pewnością zadziałać i działa dla mnie.

+0

Dzięki, rozwiążemy sprawę po lunchu. – aknuds1

+0

Okazuje się, że wyjątek został faktycznie złapany, ale komunikat potwierdzenia nie jest wypisywany na konsolę, zanim naciśnie klawisz, aby zakończyć program. Dlatego nie zauważyłem najpierw, że wiadomość została wydrukowana. Odgadnij asynchronię trochę się przyzwyczaić :) – aknuds1

+0

Bardzo dziękuję za wyjaśnienie, jak wyjątki są obsługiwane z oczekiwaniem, bardzo przydatne do mojego zrozumienia. – aknuds1

Powiązane problemy