2009-07-21 9 views

Antwort

7

Was ist Ihre Meinung in der Behandlung von Ausnahmen innerhalb der Ausführung eines Threads?

Sie sollten Ausnahmen wann immer möglich behandeln und wann immer Sie Ausnahmen erwarten. Klarstellung: Ich stimme John völlig zu, dass Sie nicht überall mit Ausnahmen umgehen sollten - nur dort, wo Sie etwas dagegen tun können. Sie sollten jedoch niemals eine Ausnahme in einem Thread unbehandelt behandeln lassen, da dies zu schwerwiegenden Problemen führen kann. Habe einen Root-Exception-Handler und lass deinen Thread elegant ablaufen (nach der Protokollierung des Problems usw.)

Genauer gesagt, was passiert, wenn der Thread in den Catch-Block einer try-catch-Klausel geworfen wird?

Meinten Sie: Was, wenn die Ausnahme innerhalb des catch-Blocks geworfen wird? Naja, dann wird es vom aktuellen Try-Catch-Block unbehandelt. Es empfiehlt sich, nicht zu viel Verarbeitung in einen Catch-Block zu schreiben, um diese Situation so weit wie möglich zu vermeiden.

Und was passiert mit dem Thread, wenn der Thread nicht behandelt wird?

Meinten Sie: Was passiert mit dem Thread, wenn die Ausnahme nicht behandelt wird? Es stirbt.

Und wie Ben erwähnt:

Eine abgefangene Ausnahme in einem Thread eine UnhandledException in der AppDomain des Thread auslöst. Sie können durch Hinzufügen eines Ereignishandler für diese beobachten:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 
+0

danke für den Tippfehler – weilin8

+0

@rein: nicht nur der Thread stirbt; Es nimmt den gesamten Prozess auf. –

+0

Ich würde empfehlen, die Informationen in Bens Antwort in Ihre letzte Aussage einzubauen. Der Thread stirbt, wenn es eine nicht behandelte Ausnahme gibt, aber es hört nicht auf. Die Ausnahme wird in der Kette auf die AppDomain übertragen und Ihre App wird beendet, wenn Sie keinen anderen Handler dafür haben. – jasonh

4

Eine abgefangene Ausnahme in einem Thread löst einen UnhandledException in der AppDomain Thread.

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

+0

Beachten Sie jedoch, dass Sie die Ausnahme im herkömmlichen Sinne "behandeln" können. Nachdem dieser Event-Handler ausgeführt wurde, wird die AppDomain wahrscheinlich gelöscht. Diese Verwendung dieses Ereignisses dient hauptsächlich dazu, Informationen über Ausnahmen oder ähnliche Aktionen protokollieren zu können. –

+0

Ja - das hätte ich erwähnen sollen. –

7

Ich muss nicht zustimmen ren oder zumindest mit dem, was es klingt wie er meinte: Sie können durch Hinzufügen eines Event-Handler für diese beobachten.

Nur Ausnahmen behandeln, wenn Sie tatsächlich behandeln sie können. Nur wenn Sie etwas tun können, was falsch gelaufen ist, oder Informationen hinzufügen. Behandle sie nicht, nur weil du kannst.

try { 
    // .. 
} catch (Exception ex) { 
    Console.WriteLine(ex.Message); 
} 

Die oben ist sehr schlecht. Zuerst zeigen Sie nicht die gesamte Ausnahme an, sondern nur die Nachricht. Zweitens lassen Sie die Dinge weiterlaufen, und Sie wissen nicht, in welchem ​​Status sich der Prozess befindet.

+0

Einverstanden. Ich wollte nicht implizieren, dass es um jedes Bit Code try-catch-Blöcke geben sollte. Danke, dass du das verstanden hast. – rein

+0

stimme ich voll und ganz zu. Der Ton der Antwort des Zügels (obwohl er klarstellte, dass er das nicht implizieren wollte) könnte für Anfänger sein, dass das Schreiben von Versuch-Fang-Blöcken eine gute Sache ist. Ich würde sagen, versuche Code ausnahmesicher zu schreiben, mit so wenig try-catch-Blöcken wie möglich; und erst dann kümmern Sie sich um Ausnahmen, die Sie in sehr speziellen Fällen tatsächlich behandeln können. Achten Sie nur auf der obersten Ebene Ihrer Anwendung (und möglicherweise an den Hauptgrenzen Ihrer Anwendungsebenen) darauf, alle Ausnahmen abzufangen (für die Meldung und das ordnungsgemäße Ablegen Ihrer App). – jeroenh

1

Nicht behandelte Ausnahmen in einem Thread verursachen, dass Ihr Prozess stirbt und mit einer nicht hilfreichen Nachricht in Ihrem Ereignisprotokoll stirbt.

Es ist eine gute Übung, in jedem Thread Top-Level-Exception-Handler zu verwenden, die protokollieren (und möglicherweise erneut werfen), wie auch einen Appdomain-Exception-Handler zu installieren, wie die anderen Antworten erwähnen.

0

Wenn Sie denken, dass Sie mit einer Ausnahme umgehen können, sollten Sie sie abfangen. Alle anderen Ausnahmen, die nicht behandelt werden können, sollten an die Oberfläche des Stapels gelangen, wo, wenn auf dem Weg kein geeigneter Handler gefunden wird, der Thread absterben wird.

Sie sollten keinen Code in einem catch-Block schreiben, der eine weitere Ausnahme auslösen könnte, aber wenn Sie möchten, können Sie einen weiteren try-catch-Block verschachteln.

0

Die .net-Ausnahmemechanismen bieten grundsätzlich keine gute Möglichkeit, eine Ausnahme während der Ausführung eines catch-Blocks oder während der Ausführung eines "finally" -Blocks zu behandeln, während eine andere Ausnahme aussteht. Eine ordnungsgemäße Handhabung würde erfordern, dass .net einen zusammengesetzten Ausnahmetyp unterstützt, der von "Fang" -Blöcken für eine seiner Komponenten erfasst werden könnte, der jedoch automatisch den Aufrufstapel erneut aufruft, bis alle Bestandteile verarbeitet worden sind. Leider bietet .net keine solchen zusammengesetzten Ausnahmetypen. Während man benutzerdefinierte Typen so definieren und verwenden könnte, um eine solche Semantik zu erhalten, wäre der Code für ihre Verwendung eher hässlich und würde sich nicht gut mit Ausnahmen integrieren, die anderer Code auslösen könnte. Folglich steht man vor der Wahl: die neue Ausnahme zu unterdrücken und die alte ausbreiten zu lassen, die neue propagieren lassen, die alte propagieren lassen oder ein zusammengesetztes Ausnahme-Objekt erstellen, das nur mit einem bekannten Code behandelt werden kann danach suchen. Keine davon ist besonders angenehm. Welche davon am besten ist, hängt vom Verständnis der Bedingungen ab, was die verschiedenen Ausnahmetypen darstellen und was der Anrufcode mit ihnen zu tun hat.

Verwandte Themen