2013-07-25 16 views
7

W poprzednich wersjach MonoTouch, kiedyś to zrobić, aby ignorować niepostrzeżenie wyjątki:Jak zignorować nieobsługiwane wyjątki przy pomocy async/await w MonoTouch?

TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e) { 
    Console.WriteLine (e); 
    e.SetObserved(); 
}; 

czy jest to dobra praktyka jest dyskusyjna, ale chciałbym wiedzieć, aby osiągnąć ten sam efekt z async/await słów kluczowych now officially supported in Xamarin.iOS 6.4.

Oto kod używam do testowania:

async void OnClick (object sender, EventArgs e) 
{ 
    await Task.Run (() => { throw new Exception(); }); 
} 

Kiedy go uruchomić, debugger wstrzymuje w AsyncVoidMethodBuilder:

enter image description here

Czytałem, że .NET 4.5 podobno changed the behaviour so unobserved exceptions don't crash the app -ale to nie pomaga, jeśli wyjątki są publikowane w kontekście synchronizacji UIKit, gdzie nie mogę ich obsłużyć.

Czy istnieje sposób, aby zignorować niezobowiązujące wyjątki od await w MonoTouch?

+1

Wspominasz o tym, że "zatrzymuje się" w 'AsyncVoidMethodBuilder'. Czy to oznacza, że ​​jeśli uderzysz dalej, wyjątek zostanie ostatecznie połknięty przez twojego przewodnika? Czy jest to przypadek, w którym tylko debuger zatrzymuje się na tym wyjątku? Poza tym artykuł, do którego się odwołujesz, zawiera niektóre ustawienia app.config, dzięki którym wyjątek działa jak .NET 4. Czy byłoby to pomocne? –

+0

@Brad: Jeśli kliknę przycisk Dalej, proces się zawiesi, ponieważ wyjątek zostanie ponownie zgłoszony w wątku interfejsu użytkownika przez podstawowy "UIKitSynchronizationContext". Ustawienia konfiguracyjne mają na celu zachowanie * bardziej rygorystyczne *, więc nie powinny być pomocne. Podniosłeś jednak ważny punkt; w poprzednich wersjach udało mi się wychwycić wyjątki w programie Unobserved handler, pomimo tego, że został zgłoszony w wątku interfejsu użytkownika. –

+1

Dostępne są różne Nieobserwowalne procedury obsługi dla zadań, AppDomain itp. Spróbuj użyć interfejsu specyficznego dla interfejsu użytkownika. Oczekuję ponownego wyrzucenia wyjątków w SynchronizationContext –

Odpowiedz

7

Jest to poprawne zachowanie async void metod: są powinien podnieść wyjątek na SynchronizationContext który był aktywny w czasie metoda async void zaczęło.

Zmiana, o której wspomniałeś w .NET 4.5, dotyczy tylko niezastrzeżonych wyjątków od z i nie ma zastosowania do metod async void.

W świecie (Microsoft) .NET różne implementacje SynchronizationContext mają inną obsługę błędów najwyższego poziomu. Pliki WPF, WinForm i ASP.NET mają różne sposoby obsługi tego błędu, zwykle w ramach typu Application.

Przejrzałem Mono UIKit API - choć nie jestem zwykłym użytkownikiem Mono - i nie mógł znaleźć żadnej obsługi błędów najwyższego poziomu w UIApplication i UIKitSynchronizationContext wygląda to nie jest publiczny (lub przynajmniej nie udokumentowane).

Innym sposobem patrzenia na ten problem: zachowanie obsługi wyjątków dla async void metod ma być tak jak obsługi zdarzeń musiałaby (aby uzyskać więcej informacji, zobacz my MSDN article). Tak więc możesz odpowiedzieć na pytanie z innym pytaniem: w UIKit, jak poradzisz sobie z tym wyjątkiem?

void OnClick (object sender, EventArgs e) 
{ 
    throw new Exception(); 
} 

W taki sam sposób poradzisz sobie z wyjątkiem async void.

Ewentualnie, jeśli chcesz zachować używając UnobservedTaskException, można po prostu nie zauważyć wyjątku zadania (w kodzie async void, Task.Run zwraca zadanie, które pobiera wyjątek, a ty obserwując go za pomocą await):

void OnClick (object sender, EventArgs e) 
{ 
    Task.Run(() => { throw new Exception(); }); 
} 

Zalecam jednak używanie async void do obsługi zdarzeń i (ostatecznie) await wszystkich zadań. Zapewni to, że nie otrzymujesz żadnych "cichych błędów" (ignorowanych wyjątków zadań), w których program przestaje działać poprawnie i nie wiesz dlaczego.

+0

Dzięki, to ma sens! Nie zdawałem sobie sprawy, że obserwuję wyjątek od zadania przez "czekanie na niego". Teraz, gdybym tylko wiedział, jak radzić sobie z wyjątkami UIKit :-) –

+1

Dan, Czy znalazłeś sposób na obserwowanie tych wyjątków UIKit? –

+1

Cześć Dan, to samo pytanie, czy zdołałeś poradzić sobie z wyjątkami UIKit? – Fabien