2013-07-25 7 views
7

In früheren Versionen von Monotouch, habe ich dies zu tun unbeobachtet Ausnahmen zu ignorieren:Wie ignoriere ich unbeobachtete Ausnahmen mit async/await in MonoTouch?

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

Ob es eine gute Praxis ist umstritten ist, aber ich mag die gleiche Wirkung mit async/await Stichwörter wissen, zu erreichen now officially supported in Xamarin.iOS 6.4.

Hier ist der Code ich zum Testen verwenden:

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

Wenn ich es laufen, Pausen Debugger in AsyncVoidMethodBuilder:

enter image description here

ich, dass .NET 4.5 angeblich changed the behaviour so unobserved exceptions don't crash the app -aber dies lesen Es hilft nicht, wenn Ausnahmen im UIKit-Synchronisationskontext gepostet werden, wo ich sie nicht behandeln kann.

Gibt es eine Möglichkeit, unbeobachtete Ausnahmen von await in MonoTouch zu ignorieren?

+1

Sie erwähnen es "Pausen" in 'AsyncVoidMethodBuilder'. Bedeutet das, dass, wenn Sie fortfahren, die Ausnahme letztendlich von Ihrem Hundeführer verschluckt wird? Ist dies ein Fall, in dem nur der Debugger diese Ausnahme anhält? Außerdem enthält der Artikel, auf den Sie verwiesen haben, einige app.config-Einstellungen, damit die Ausnahme funktioniert wie .NET 4. Wäre das hilfreich? –

+0

@Brad: Wenn ich "continue" drücke, stürzt der Prozess ab, weil die Ausnahme vom zugrunde liegenden 'UIKitSynchronizationContext' erneut auf den UI-Thread geworfen wird. Die Konfigurationseinstellungen dienen dazu, das Verhalten * strikter * zu machen, so dass sie nicht hilfreich sein sollten. Du hast einen gültigen Punkt angesprochen. In früheren Versionen konnte ich die Ausnahmen im Unobserved-Handler abfangen, obwohl sie auf den UI-Thread geworfen wurden. –

+1

Es gibt verschiedene unbeobachtete Handler für Tasks, die AppDomain usw. Versuchen Sie es mit dem für die Benutzeroberfläche spezifischen. Wartet, dass Ausnahmen auf dem SynchronizationContext erneut gesendet werden –

Antwort

7

Dies ist das richtige Verhalten von async void Methoden: sie sind sollten die Ausnahme auf den SynchronizationContext erhöhen, die zum Zeitpunkt der async void Methode gestartet aktiv war.

Die Änderung, die Sie in .NET 4.5 erwähnten, behandelt nur unbeobachtete Aufgaben Ausnahmen und gilt nicht für async void Methoden.

In der (Microsoft) .NET-Welt haben verschiedene SynchronizationContext Implementierungen unterschiedliche Top-Level-Fehlerbehandlung. WPF, WinForms und ASP.NET haben alle verschiedene Möglichkeiten, diesen Fehler zu behandeln, normalerweise als Teil eines Application-Typs.

Ich schaute durch Monos UIKit API - obwohl ich kein normaler Mono-Benutzer bin - und konnte keine Fehlerbehandlung auf oberster Ebene in UIApplication finden, und UIKitSynchronizationContext sieht aus, als wäre es nicht öffentlich (oder zumindest nicht dokumentiert).

Ein anderer Weg, um dieses Problem zu betrachten: die Ausnahmebehandlung Verhalten für async void Methoden konzipiert würde (für weitere Informationen siehe my MSDN article) haben wie Event-Handler zu sein. Sie können die Frage also mit einer anderen Frage beantworten: Wie würden Sie in UIKit mit dieser Ausnahme umgehen?

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

Sie würden Ihre async void Ausnahme in genau der gleichen Weise behandeln.

Alternativ, wenn Sie UnobservedTaskException Verwendung behalten möchten, können Sie einfach nicht die Aufgabe Ausnahme beobachten (in Ihrem async void Code, kehrt Task.Run eine Aufgabe, die eine Ausnahme bekommt, und Sie beobachten sie unter Verwendung await):

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

Allerdings empfehle ich async void für Event-Handler verwenden und (eventuell) await ing alle Ihre Aufgaben. Dies stellt sicher, dass Sie keine "stillen Fehler" (ignorierte Aufgabenausnahmen) erhalten, bei denen Ihr Programm nicht mehr ordnungsgemäß funktioniert und Sie nicht wissen, warum.

+0

Danke, das macht Sinn! Ich habe nicht bemerkt, dass ich eine Aufgabenausnahme beobachte, indem ich sie abwarte. Nun, wenn ich nur wüsste, wie man mit UIKit-Ausnahmen umgeht :-) –

+1

Dan, Hast du irgendeine Möglichkeit gefunden, diese UIKit-Ausnahmen zu beachten? –

+1

Hallo Dan, gleiche Frage, hast du es geschafft, die UIKit-Ausnahmen zu behandeln? – Fabien