什么时候终于运行,如果你从catch块中抛出一个exception?

try { // Do stuff } catch (Exception e) { throw; } finally { // Clean up } 

在上面的块中,finally块是什么时候被调用的? e投掷之前还是最后打电话再抓?

它会在e被重新抛出后被调用(即在catch块被执行之后)

编辑这7年后 – 一个重要的注意事项是,如果e没有被try / catch块进一步调用堆栈或由全局exception处理程序处理,那么finally可能永远不会执行。

为什么不尝试:

 outer try inner try inner catch inner finally outer catch outer finally 

与代码(格式为垂直空间):

 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"); } } 

您的示例将与此代码的行为相同:

 try { try { // Do stuff } catch(Exception e) { throw e; } } finally { // Clean up } 

作为一个侧面说明,如果你的意思是throw e; (也就是说,抛出刚刚捕获的exception),那么throw;就好多了throw; ,因为这将保留原始的堆栈轨迹,而不是创build一个新的。

看完所有的答案后,看起来最终的答案是这样的

  • 如果在catch块中重新抛出一个exception,并且该exception被捕获到另一个catch块中,则根据文档执行所有操作。

  • 但是,如果重新处理的exception是未处理的,那么finally永远不会执行。

我在VS2010 w / C#4.0中testing了这个代码示例

 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(); } 

这是输出:

例1:在另一个try块内重新抛出:
– 外尝试
—-内心尝试
—-内抓
—-内心终于
– 捕捉
– 终于
好哇!

例2:重新抛出另一个try块:
– 尝试
– 抓住

未处理的exception:System.Exception:引发types'System.Exception'的exception。
在C:\ local source \ ConsoleApplication1 \ Program.cs中的ConsoleApplication1.Program.Main()中:第53行

如果catch处理程序块中有一个未处理的exception,则finally块将被完全调用0

  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:\用户\pipe理员\文件\ TestExceptionNesting \ BIN \发布> TestExceptionNesting.exe

在尝试

在捕获

未处理的exception:System.DivideByZeroException:尝试除以零。 TestExceptionNesting.Program.Main(String [] args)在C:\ users \ administrator \ documents \ TestExceptionNesting \ TestExceptionNesting.cs:line 22

C:\用户\pipe理员\文件\ TestExceptionNesting \ BIN \发布>

今天在接受采访的时候,我问到了这个问题,面试官不停地回头:“你确定最后不会打电话吗?” 我不确定这是否意味着一个诡计问题,或者面试官有其他想法,并且写了错误的代码供我debugging,所以我回到了家,试了一下(构build和运行,没有debugging器交互),只是为了让我rest。

一个简单的方法告诉也是debugging你的代码,并注意到最后被调用时。

使用C#控制台应用程序进行testing,抛出exception后执行finally代码:“应用程序错误对话框”已存在,在select“closures程序”选项后,在该控制台窗口中执行finally块。 但是在最后的代码块中设置断点,我永远不会打到它。 debugging器不停地在throw语句中停止。 这是我的testing代码:

  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中debugging – .NET Framework 4.0