When is finally run if you throw an exception from the catch block?
1 2 3 4 5 6 7 8 9 | try { // Do stuff } catch (Exception e) { throw; } finally { // Clean up } |
在上面的块中,何时调用finally块?在投掷之前还是最后被召唤然后被抓住?
它将在重新抛出e之后调用(即在执行catch块之后)
在7年后编辑这篇文章-一个重要的注意事项是,如果在调用堆栈上更远处的try/catch块没有捕获到
为什么不试试呢?
1 2 3 4 5 6 | outer try inner try inner catch inner finally outer catch outer finally |
带代码(格式为垂直空格):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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"); } } |
在阅读了所有的答案之后,最终的答案似乎取决于:
如果在catch块中重新抛出异常,并且该异常被捕获在另一个catch块中,那么所有操作都将根据文档执行。
但是,如果重新生成的异常未经处理,则最终不会执行。
我在VS2010 w/c_4.0中测试了这个代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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(); } |
以下是输出:
Example 1: re-throw inside of another try block:
--outer try
----inner try
----inner catch
----inner finally
--outer catch
--outer finally
Huzzah!Example 2: re-throw outside of another try block:
--try
--catchUnhandled Exception: System.Exception: Exception of type 'System.Exception' was thrown.
at ConsoleApplication1.Program.Main() in C:\local source\ConsoleApplication1\Program.cs:line 53
您的示例的行为与此代码相同:
1 2 3 4 5 6 7 8 9 | try { try { // Do stuff } catch(Exception e) { throw e; } } finally { // Clean up } |
作为旁注,如果您真正指的是
如果在catch处理程序块内有未处理的异常,那么finally块将被精确调用零次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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"); } } |
输出:
C:\users\administrator\documents\TestExceptionNesting\bin
elease>TestExceptionNesting.exein the try
in the catch
Unhandled Exception: System.DivideByZeroException: Attempted to divide
by zero. at TestExceptionNesting.Program.Main(String[] args) in
C:\users\administrator\documents\TestExceptionNesting\TestExceptionNesting.cs:line 22C:\users\administrator\documents\TestExceptionNesting\bin
elease>
我今天在一次面试中被问到这个问题,面试官不停地回问:"你确定最后一个不会被打电话吗?"我不确定这是否意味着一个技巧问题,或者面试官有其他想法,并为我编写了错误的代码进行调试,所以我回到家并尝试了它(构建和运行,没有调试程序交互),只是为了让我的头脑休息一下。
一个简单的方法是调试代码,并注意最后一次调用的时间。
使用C控制台应用程序进行测试时,最终代码在引发异常后执行:存在"应用程序错误对话框",选择"关闭程序"选项后,最终块在该控制台窗口中执行。但是在finally代码块中设置断点,我永远也打不到它。调试器一直在throw语句处停止。这是我的测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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!"); } } } |
在VS2010-.NET Framework 4.0中调试