try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Wann wird im obigen Block der finally-Block aufgerufen? Vor dem Werfen von e oder wird endlich gerufen und dann fangen?
try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Wann wird im obigen Block der finally-Block aufgerufen? Vor dem Werfen von e oder wird endlich gerufen und dann fangen?
Antworten:
Es würde aufgerufen, nachdem e erneut geworfen wurde (dh nachdem der catch-Block ausgeführt wurde).
7 Jahre später bearbeiten - Ein wichtiger Hinweis ist, dass eder finallyBlock möglicherweise überhaupt nicht ausgeführt wird, wenn er nicht von einem Try / Catch-Block weiter oben im Aufrufstapel abgefangen oder von einem globalen Ausnahmebehandler behandelt wird .
finallynicht , wenn die Ausnahme im vorhergehenden geworfen ausgeführt wird catchnie ist gefangen in einem äußeren try- catchBlock!
Warum probieren Sie es nicht aus:
outer try
inner try
inner catch
inner finally
outer catch
outer finally
mit Code (formatiert für vertikalen Raum):
static void Main() {
try {
Console.WriteLine("outer try");
DoIt();
} catch {
Console.WriteLine("outer catch");
// swallow
} finally {
Console.WriteLine("outer finally");
}
}
static void DoIt() {
try {
Console.WriteLine("inner try");
int i = 0;
Console.WriteLine(12 / i); // oops
} catch (Exception e) {
Console.WriteLine("inner catch");
throw e; // or "throw", or "throw anything"
} finally {
Console.WriteLine("inner finally");
}
}
outer try inner try inner catch Unhandled Exception: System.DivideByZeroException...
Nachdem Sie alle Antworten hier gelesen haben, sieht es so aus, als ob die endgültige Antwort davon abhängt :
Wenn Sie eine Ausnahme innerhalb des catch-Blocks erneut auslösen und diese Ausnahme innerhalb eines anderen catch-Blocks abgefangen wird, wird alles gemäß der Dokumentation ausgeführt.
Wenn die erneut ausgelöste Ausnahme jedoch nicht behandelt wird, wird sie schließlich nie ausgeführt.
Ich habe dieses Codebeispiel in VS2010 mit C # 4.0 getestet
static void Main()
{
Console.WriteLine("Example 1: re-throw inside of another try block:");
try
{
Console.WriteLine("--outer try");
try
{
Console.WriteLine("----inner try");
throw new Exception();
}
catch
{
Console.WriteLine("----inner catch");
throw;
}
finally
{
Console.WriteLine("----inner finally");
}
}
catch
{
Console.WriteLine("--outer catch");
// swallow
}
finally
{
Console.WriteLine("--outer finally");
}
Console.WriteLine("Huzzah!");
Console.WriteLine();
Console.WriteLine("Example 2: re-throw outside of another try block:");
try
{
Console.WriteLine("--try");
throw new Exception();
}
catch
{
Console.WriteLine("--catch");
throw;
}
finally
{
Console.WriteLine("--finally");
}
Console.ReadLine();
}
Hier ist die Ausgabe:
Beispiel 1: Werfen Sie erneut in einen anderen Versuchsblock:
--outer try
---- inner try
---- inner catch
---- inner finally -
outer catch
--outer finally
Huzzah!Beispiel 2: Werfen Sie erneut außerhalb eines anderen Versuchsblocks:
--try
--catchNicht behandelte Ausnahme: System.Exception: Ausnahme vom Typ 'System.Exception' wurde ausgelöst.
unter ConsoleApplication1.Program.Main () in C: \ local source \ ConsoleApplication1 \ Program.cs: Zeile 53
Ihr Beispiel würde sich mit diesem Code identisch verhalten:
try {
try {
// Do stuff
} catch(Exception e) {
throw e;
}
} finally {
// Clean up
}
Nebenbei bemerkt, wenn Sie wirklich meinen throw e;(dh dieselbe Ausnahme auslösen, die Sie gerade abgefangen haben), ist es viel besser, dies einfach zu tun throw;, da dadurch die ursprüngliche Stapelverfolgung beibehalten wird, anstatt eine neue zu erstellen.
finallyBlock wird tatsächlich nach dem catchBlock ausgeführt (selbst wenn der catch-Block die Ausnahme erneut auslöst), was mein Snippet zu veranschaulichen versucht.
tryBlocks davon hat meine Antwort einen "try-catch". Ich versuche, das Verhalten des dreiteiligen Konstrukts anhand von zwei zweiteiligen Konstrukten zu erklären. Ich sehe kein Anzeichen für einen zweiten tryBlock in der ursprünglichen Frage, daher verstehe ich nicht, woher Sie das bekommen.
Wenn es innerhalb eines Catch-Handler-Blocks eine nicht behandelte Ausnahme gibt, wird der finally-Block genau null Mal aufgerufen
static void Main(string[] args)
{
try
{
Console.WriteLine("in the try");
int d = 0;
int k = 0 / d;
}
catch (Exception e)
{
Console.WriteLine("in the catch");
throw;
}
finally
{
Console.WriteLine("In the finally");
}
}
Ausgabe:
C: \ Benutzer \ Administrator \ Dokumente \ TestExceptionNesting \ bin \ Release> TestExceptionNesting.exe
im Versuch
im Fang
Nicht behandelte Ausnahme: System.DivideByZeroException: Es wurde versucht, durch Null zu teilen. bei TestExceptionNesting.Program.Main (String [] args) in C: \ Benutzer \ Administrator \ Dokumente \ TestExceptionNesting \ TestExceptionNesting.cs: Zeile 22
C: \ Benutzer \ Administrator \ Dokumente \ TestExceptionNesting \ bin \ release>
Diese Frage wurde mir heute bei einem Interview gestellt und der Interviewer ging immer wieder zurück. "Bist du sicher, dass der endlich nicht angerufen wird?" Ich war mir nicht sicher, ob es sich um eine Trickfrage handelte oder ob der Interviewer etwas anderes im Sinn hatte und schrieb den falschen Code zum Debuggen, also kam ich nach Hause und versuchte es (Erstellen und Ausführen, keine Debugger-Interaktion), nur um mich zu überlegen sich ausruhen.
Beim Testen mit einer C # -Konsolenanwendung wurde der finally-Code ausgeführt, nachdem die Ausnahme ausgelöst wurde: Das Dialogfeld "Anwendungsfehler" war vorhanden, und nachdem Sie die Option "Programm schließen" ausgewählt haben, wurde der finally-Block in diesem Konsolenfenster ausgeführt. Aber wenn ich die Bruchstelle innerhalb des endgültigen Codeblocks setze, kann ich sie niemals treffen. Der Debugger bleibt bei der throw-Anweisung stehen. Hier ist mein Testcode:
class Program
{
static void Main(string[] args)
{
string msg;
Console.WriteLine(string.Format("GetRandomNuber returned: {0}{1}", GetRandomNumber(out msg), msg) == "" ? "" : "An error has occurred: " + msg);
}
static int GetRandomNumber(out string errorMessage)
{
int result = 0;
try
{
errorMessage = "";
int test = 0;
result = 3/test;
return result;
}
catch (Exception ex)
{
errorMessage = ex.Message;
throw ex;
}
finally
{
Console.WriteLine("finally block!");
}
}
}
Debuggen in VS2010 - .NET Framework 4.0