Was passiert genau , wenn ein finally-Block eine Ausnahme auslöst?
Was passiert insbesondere, wenn die Ausnahme in der Mitte eines finally-Blocks ausgelöst wird? Werden die restlichen Anweisungen (nach) in diesem Block aufgerufen?
Mir ist bewusst, dass sich Ausnahmen nach oben ausbreiten werden.
c#
exception
exception-handling
try-catch-finally
Jack Kada
quelle
quelle
Antworten:
Diese Ausnahme breitet sich immer weiter aus und wird (kann) auf einer höheren Ebene behandelt.
Ihr endgültiger Block wird nicht über den Punkt hinaus abgeschlossen, an dem die Ausnahme ausgelöst wird.
Wenn der finally-Block während der Behandlung einer früheren Ausnahme ausgeführt wurde, geht diese erste Ausnahme verloren.
quelle
ThreadAbortException
der Fall ist , wird der gesamte endgültige Block zuerst beendet, da es sich um einen kritischen Abschnitt handelt.Bei Fragen wie diesen öffne ich normalerweise ein leeres Konsolenanwendungsprojekt in Visual Studio und schreibe ein kleines Beispielprogramm:
Wenn Sie das Programm ausführen, sehen Sie die genaue Reihenfolge, in der
catch
undfinally
Blöcke ausgeführt werden. Beachten Sie, dass Code im finally-Block nach dem Auslösen der Ausnahme nicht ausgeführt wird (in diesem Beispielprogramm warnt Visual Studio Sie sogar, dass nicht erreichbarer Code erkannt wurde):Zusätzliche Bemerkung
Wie Michael Damatov betonte, wird eine Ausnahme vom
try
Block "gegessen", wenn Sie sie nicht in einem (inneren)catch
Block behandeln. Tatsächlich wird im obigen Beispiel die erneut ausgelöste Ausnahme nicht im äußeren Catch-Block angezeigt. Um dies noch deutlicher zu machen, schauen Sie sich das folgende leicht modifizierte Beispiel an:Wie Sie aus der Ausgabe sehen können, ist die innere Ausnahme "verloren" (dh ignoriert):
quelle
finally
Block wird (fast) immer ausgeführt, dies gilt auch in diesem Fall für den inneren finally-Block (probieren Sie einfach das Beispielprogramm selbst aus (ein finally-Block wird im Falle eines nicht wiederherstellbaren Blocks nicht ausgeführt Ausnahme, zB eineEngineExecutionException
, aber in einem solchen Fall wird Ihr Programm trotzdem sofort beendet).Wenn eine Ausnahme aussteht (wenn der
try
Block eine,finally
aber keine hatcatch
), ersetzt die neue Ausnahme diese.Wenn keine Ausnahme ansteht, funktioniert dies genauso wie das Auslösen einer Ausnahme außerhalb des
finally
Blocks.quelle
catch
Block daß (Wieder-) eine Ausnahme ausgelöst.Die Ausnahme wird weitergegeben.
quelle
Schnelles (und ziemlich offensichtliches) Snippet zum Speichern der "ursprünglichen Ausnahme" (in
try
Block geworfen ) und zum Opfer von "endgültige Ausnahme" (infinally
Block geworfen ), falls das Original für Sie wichtiger ist:Wenn der obige Code ausgeführt wird, überträgt "Original Exception" den Aufrufstapel und "Endlich Exception" geht verloren.
quelle
Ich musste dies tun, um einen Fehler beim Schließen eines Streams zu erkennen, der aufgrund einer Ausnahme nie geöffnet wurde.
Wenn die webRequest erstellt wurde, aber während des ein Verbindungsfehler aufgetreten ist
Dann würde der Endlich eine Ausnahme abfangen, die versucht, Verbindungen zu schließen, die er für offen hielt, weil die webRequest erstellt wurde.
Wenn der Code schließlich keinen Try-Catch enthalten würde, würde dieser Code beim Bereinigen der webRequest eine nicht behandelte Ausnahme verursachen
Von dort aus würde der Code beendet, ohne den aufgetretenen Fehler ordnungsgemäß zu behandeln, und daher Probleme für die aufrufende Methode verursachen.
Hoffe das hilft als Beispiel
quelle
Wenn Sie eine Ausnahme auslösen, während eine andere Ausnahme aktiv ist, wird die erste Ausnahme durch die zweite (spätere) Ausnahme ersetzt.
Hier ist ein Code, der veranschaulicht, was passiert:
quelle
Vor einigen Monaten stand ich auch so etwas gegenüber,
Um dieses Problem zu lösen, habe ich eine Utility-Klasse wie erstellt
Und so verwendet
Wenn Sie jedoch Parameter und Rückgabetypen verwenden möchten, ist dies eine andere Geschichte
quelle
Die Art und Weise, wie die von CodeA und CodeB ausgelösten Ausnahmen behandelt werden, ist dieselbe.
Eine in einem
finally
Block ausgelöste Ausnahme hat nichts Besonderes. Behandeln Sie sie als den durch Code B ausgelösten Ausnahmefall.quelle
Die Ausnahme breitet sich aus und sollte auf einer höheren Ebene behandelt werden. Wenn die Ausnahme nicht auf der höheren Ebene behandelt wird, stürzt die Anwendung ab. Die Blockausführung "finally" stoppt an dem Punkt, an dem die Ausnahme ausgelöst wird.
Unabhängig davon, ob es eine Ausnahme gibt oder nicht, wird die Ausführung des Blocks "finally" garantiert.
Wenn der "finally" -Block ausgeführt wird, nachdem im try-Block eine Ausnahme aufgetreten ist,
und wenn diese Ausnahme nicht behandelt wird
und wenn der finally-Block eine Ausnahme auslöst
Dann geht die ursprüngliche Ausnahme, die im try-Block aufgetreten ist, verloren.
Toller Artikel für Details
quelle
Es wird eine Ausnahme ausgelöst;) Sie können diese Ausnahme in einer anderen catch-Klausel abfangen.
quelle