Wir haben eine WPF-Anwendung, bei der Teile davon zur Laufzeit Ausnahmen auslösen können. Ich möchte alle nicht behandelten Ausnahmen global abfangen und protokollieren, aber ansonsten die Programmausführung fortsetzen, als wäre nichts passiert (ein bisschen wie bei VBs On Error Resume Next
).
Ist das in C # möglich? Und wenn ja, wo genau müsste ich den Code für die Ausnahmebehandlung eingeben?
Derzeit sehe ich keinen einzigen Punkt, an dem ich ein try
/ catch
umschließen könnte und der alle möglichen Ausnahmen abfangen würde. Und selbst dann hätte ich alles verlassen, was wegen des Fangs hingerichtet wurde. Oder denke ich hier in schrecklich falsche Richtungen?
ETA: Weil viele Leute unten darauf hingewiesen haben: Die Anwendung ist nicht für die Steuerung von Kernkraftwerken. Wenn es abstürzt, ist es keine große Sache, aber zufällige Ausnahmen, die hauptsächlich mit der Benutzeroberfläche zusammenhängen, sind in dem Kontext, in dem es verwendet wird, ein Ärgernis. Es gab (und gibt es wahrscheinlich immer noch) einige davon und da es eine Plugin-Architektur verwendet und möglicherweise von anderen erweitert wird (in diesem Fall auch von Studenten; also keine erfahrenen Entwickler, die in der Lage sind, vollständig fehlerfreien Code zu schreiben).
Was die Ausnahmen betrifft, die abgefangen werden: Ich protokolliere sie in einer Protokolldatei, einschließlich der vollständigen Stapelverfolgung. Das war der springende Punkt dieser Übung. Nur um den Leuten entgegenzuwirken, die meine Analogie zu VBs OERN zu wörtlich genommen haben.
Ich weiß, dass das blinde Ignorieren bestimmter Fehlerklassen gefährlich ist und meine Anwendungsinstanz beschädigen kann. Wie bereits erwähnt, ist dieses Programm für niemanden geschäftskritisch. Niemand, der bei klarem Verstand ist, würde das Überleben der menschlichen Zivilisation darauf wetten. Es ist einfach ein kleines Werkzeug zum Testen bestimmter Designansätze. Softwareentwicklung.
Für die sofortige Verwendung der Anwendung können in einer Ausnahme nicht viele Dinge passieren:
- Keine Ausnahmebehandlung - Fehlerdialog und Anwendungs-Exit. Das Experiment muss wiederholt werden, wenn auch wahrscheinlich mit einem anderen Probanden. Es wurden keine Fehler protokolliert, was bedauerlich ist.
- Allgemeine Ausnahmebehandlung - harmloser Fehler abgefangen, kein Schaden angerichtet. Dies sollte der übliche Fall sein, der anhand aller Fehler beurteilt wird, die wir während der Entwicklung gesehen haben. Das Ignorieren dieser Art von Fehlern sollte keine unmittelbaren Konsequenzen haben. Die Kerndatenstrukturen sind so gut getestet, dass sie dies leicht überleben können.
- Allgemeine Ausnahmebehandlung - schwerwiegender Fehler, möglicherweise Absturz zu einem späteren Zeitpunkt. Dies kann selten vorkommen. Wir haben es bisher noch nie gesehen. Der Fehler wird trotzdem protokolliert und ein Absturz kann unvermeidlich sein. Dies ist also konzeptionell dem allerersten Fall ähnlich. Nur dass wir einen Stack-Trace haben. Und in den meisten Fällen wird der Benutzer es nicht einmal bemerken.
Zu den vom Programm generierten Versuchsdaten: Ein schwerwiegender Fehler würde im schlimmsten Fall nur dazu führen, dass keine Daten aufgezeichnet werden. Subtile Änderungen, die das Ergebnis des Experiments geringfügig verändern, sind ziemlich unwahrscheinlich. Und selbst in diesem Fall wurde der Fehler protokolliert, wenn die Ergebnisse zweifelhaft erscheinen. man kann diesen Datenpunkt immer noch wegwerfen, wenn es ein totaler Ausreißer ist.
Zusammenfassend: Ja, ich betrachte mich immer noch als zumindest teilweise gesund und ich betrachte keine globale Ausnahmebehandlungsroutine, die das Programm laufen lässt, als absolut böse. Wie bereits zweimal erwähnt, kann eine solche Entscheidung je nach Antrag gültig sein. In diesem Fall wurde es als eine gültige Entscheidung beurteilt und nicht als totaler und völliger Schwachsinn. Für jede andere Anwendung kann diese Entscheidung anders aussehen. Aber bitte beschuldigen Sie mich oder die anderen Leute, die an diesem Projekt gearbeitet haben, nicht, die Welt in die Luft zu jagen, nur weil wir Fehler ignorieren.
Randnotiz: Es gibt genau einen Benutzer für diese Anwendung. Es ist nicht so etwas wie Windows oder Office, das von Millionen verwendet wird, bei denen die Kosten für Ausnahmen für den Benutzer bereits sehr unterschiedlich wären.
On Error Resume Next
in C # nicht möglich ist. Nach einemException
(C # hat keine "Fehler") können Sie nicht einfach mit der nächsten Anweisung fortfahren: Die Ausführung wird in einemcatch
Block fortgesetzt - oder in einem der in den folgenden Antworten beschriebenen Ereignishandler.Antworten:
Verwenden Sie die
Application.DispatcherUnhandledException Event
. Eine Zusammenfassung finden Sie in dieser Frage (siehe Antwort von Drew Noakes ).Beachten Sie, dass es immer noch Ausnahmen gibt, die eine erfolgreiche Wiederaufnahme Ihrer Anwendung ausschließen, z. B. nach einem Stapelüberlauf, erschöpftem Speicher oder einem Verlust der Netzwerkverbindung, während Sie versuchen, in der Datenbank zu speichern.
quelle
Beispielcode mit NLog , der Ausnahmen abfängt , die von allen Threads in der AppDomain , vom UI-Dispatcher-Thread und von den asynchronen Funktionen ausgelöst werden :
App.xaml.cs:
quelle
UnhandledException
Handler nicht abgefangen . Ich musste in Windows Event Log Viewer schauen, um herauszufinden, was los war ...e.Handled = true;
an die ,UnhandledException
dass die Anwendung nicht auf UI Ausnahmen abstürztAppDomain.UnhandledException- Ereignis
quelle
Beachten Sie zusätzlich zu dem, was andere hier erwähnt haben, dass das
Application.DispatcherUnhandledException
(und seine Ähnlichkeiten ) mit kombiniert wirdin der
app.config
verhindert, dass Ihre sekundäre Thread-Ausnahme die Anwendung herunterfährt.quelle
Hier ist ein vollständiges Beispiel mit
NLog
quelle
Wie "VB's On Error Resume Next?" Das klingt irgendwie beängstigend. Die erste Empfehlung ist, es nicht zu tun. Die zweite Empfehlung ist, es nicht zu tun und nicht darüber nachzudenken. Sie müssen Ihre Fehler besser isolieren. Wie Sie dieses Problem angehen können, hängt davon ab, wie Ihr Code strukturiert ist. Wenn Sie ein Muster wie MVC oder ähnliches verwenden, sollte dies nicht zu schwierig sein und würde definitiv keinen globalen Ausnahme-Schlucker erfordern. Suchen Sie zweitens nach einer guten Protokollierungsbibliothek wie log4net oder verwenden Sie die Ablaufverfolgung. Wir müssen mehr Details wissen, z. B. über welche Arten von Ausnahmen Sie sprechen und welche Teile Ihrer Anwendung dazu führen können, dass Ausnahmen ausgelöst werden.
quelle