2013-09-26 14 views
8

Miałem nadzieję, że ktoś może mnie oświecić w kwestii, z którą mam do czynienia w związku z obsługą asynchronizacji/oczekiwania na wyjątki przy pomocy HttpClient. Pisałem jakiś kod, aby zilustrować, i to jest ścięci zarówno na urządzeniu z systemem Windows Phone 8 oraz emulatora:Prawidłowa obsługa wyjątków HttpClient w async/poczekaj

private async void SearchButton_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      HttpClient client = new HttpClient(); 
      System.Diagnostics.Debug.WriteLine("BEGIN FAULTY REQUEST:"); 
      string response = await client.GetStringAsync("http://www.ajshdgasjhdgajdhgasjhdgasjdhgasjdhgas.tk/"); 
      System.Diagnostics.Debug.WriteLine("SUCCESS:"); 
      System.Diagnostics.Debug.WriteLine(response); 
     } 
     catch (Exception exception) 
     { 
      System.Diagnostics.Debug.WriteLine("CAUGHT EXCEPTION:"); 
      System.Diagnostics.Debug.WriteLine(exception); 
     } 
    } 

dotknięcie przycisku, który wywołuje tę funkcję, produkuje następujące dane wyjściowe w konsoli debuggera, najbardziej interesujący jest te w pogrubioną:

BEGIN WADLIWA WNIOSEK:

wyjątek typu „System.Net.WebException” wystąpił w System.Windows.ni.dll i nie był obsługiwany przed zarządzany/granica natywna

Wyjątek typu „System.Net.WebException” wystąpił w System.Windows.ni.dll i nie był obsługiwany przed zarządzanym/rodzimej granicy

Pierwsza szansa wyjątek typu „system. Net.Http.HttpRequestException”wystąpił w mscorlib.ni.dll

wyjątek typu«System.Net.Http.HttpRequestException»wystąpiło w mscorlib.ni.dll i nie był obsługiwany przed zarządzanym/rodzimej granicy

ZŁO WYJĄTKIEM: (i tutaj wypisuje wyjątek HttpRequestException)

Oczywiście oczekuję błędu w tym przypadku, ponieważ URL, który wywołuję, jest nonsensem. Nie rozumiem tutaj, dlaczego debugger zgłasza, że ​​wyjątki nie są obsługiwane, gdy dane wyjściowe jednocześnie zgłaszają, że wyjątek został przechwycony. Poza tym strona interfejsu użytkownika staje się znacznie mniej responsywna podczas drukowania wyjścia, co wskazuje, że coś jest prawdopodobnie nie w porządku.

Czy to nie jest sposób obsługi wyjątków podczas pracy z asynchronizacją i czekania? Doceniam wszelkie dane wejściowe! Dzięki.

+2

Jeśli chodzi o czas reakcji nie należy uruchamiać długich procesów w przypadku UI. Powinny to być szybkie i długotrwałe procesy powinny być zakończone w innym wątku. Wypróbuj 'BackgroundWorker' http://msdn.microsoft.com/en-us/library/System.ComponentModel.BackgroundWorker.aspx – Harrison

Odpowiedz

6

To jest artefakt debuggera. Określa, że ​​wyjątek jest "nieprzechwycony", ponieważ nie został jeszcze przechwycony , a następnie. W tym przypadku jest to oczekiwane zachowanie.

Obsługujesz wyjątki poprawnie.

+2

Powiedziałbym, że jest oznaczony jako" uncaught ", ponieważ nie został przechwycony przez kod użytkownika, ale przez TPL. – usr

+0

Wyjątek nie jest obsługiwany. jest ukryty (nawet jeśli jest zalogowany do Debug.WriteLine, który nie pojawi się w trybie Release). Jeśli wbudowane wydanie, jeśli wywołanie HTTP nie powiedzie się, nie będziesz wiedział dlaczego (lub nawet, że się nie udało). – Stuart

+0

@Stuart: W przypadku kodu opublikowanego w pytaniu wyjątek zostanie przechwycony. –

0

Debugger mówi ci, że ten wyjątek jest pierwszą szansą. Gdy debugger jest dołączony do twojego procesu, otrzymuje powiadomienie o każdym zgłoszonym wyjątku, a następnie na podstawie tego, jak skonfigurowany jest debugger, zdecyduje, co z nim zrobić. Aby uzyskać więcej informacji, przejdź przez numer What is first chance exception?.

Na marginesie, wychwytywanie określonych wyjątków, aby zrozumieć, które wyjątki są oczekiwane i dlaczego.

+0

Dzięki, będę czytać! Zgadzam się z Waszą uwagą, mój aktualny scenariusz jest inny, właśnie napisałem to, aby zilustrować mój problem. –

22

Jak używasz HttpClient, spróbuj użyć response.EnsureSuccessStatusCode();

Teraz HttpClient rzuci wyjątek, gdy stan odpowiedź nie jest kodem sukces.

try 
{ 
    HttpResponseMessage response = await client.GetAsync("http://www.ajshdgasjhdgajdhgasjhdgasjdhgasjdhgas.tk/"); 
    response.EnsureSuccessStatusCode(); // Throw if not a success code. 

    // ... 
} 
catch (HttpRequestException e) 
{ 
    // Handle exception. 
} 

pierwotne źródło kodu: http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

+3

Jeśli chcesz 'response'to być typu' HttpResponseMessage' musisz użyć 'client.GetAsync'instead' client.GetStringAsync'. – kaolick