什么时候终于运行,如果你从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