try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
在上面的块中,何时调用finally块?在抛出e之前还是最终被调用然后捕获?
try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
在上面的块中,何时调用finally块?在抛出e之前还是最终被调用然后捕获?
Answers:
在e被重新抛出后(即执行catch块之后)将被调用
在这7年后进行编辑-一个重要的注意事项是,如果e没有被调用堆栈上方的try / catch块捕获或未被全局异常处理程序处理,则该finally块可能根本不会执行。
finally如果在前面抛出的异常不执行catch永远不会陷入在外try- catch块!
为什么不尝试一下:
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");
}
}
outer try inner try inner catch Unhandled Exception: System.DivideByZeroException...
看完所有答案后,看来最终答案取决于:
如果您在catch块中重新抛出异常,并且该异常被捕获在另一个catch块中,则所有操作均根据文档执行。
但是,如果未处理重引发的异常,则将永远不会执行。
我在带有C#4.0的VS2010中测试了此代码示例
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块中重新抛出:--
outer try
---- inner try
---- inner catch
---- inner finally
--outer catch
--outer finally
Huzzah!示例2:重新抛出另一个try块之外:--
try
--catch未处理的异常:System.Exception:引发了类型为“ System.Exception”的异常。
在ConsoleApplication1.Program.Main()中的C:\ local source \ ConsoleApplication1 \ Program.cs:line 53中
您的示例的行为与以下代码相同:
try {
try {
// Do stuff
} catch(Exception e) {
throw e;
}
} finally {
// Clean up
}
作为一个侧面说明,如果你真正的意思throw e;(即扔你刚好赶上了同样的异常),它是多好,只是这样做throw;,因为这将保留原始的堆栈跟踪,而不是创建一个新的。
finally实际上,该块将在该块之后运行catch(即使catch块抛出异常),这就是我的代码段试图说明的内容。
try我的回答里面有一个“ try-catch”。我试图通过使用两个2部分结构来解释3部分结构的行为。我try在原始问题中没有看到第二个障碍的迹象,所以我不明白您从哪里得到的。
如果在catch处理程序块中存在未处理的异常,则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:\ users \ administrator \ documents \ TestExceptionNesting \ bin \ Release> TestExceptionNesting.exe
在尝试
抓住
未处理的异常:System.DivideByZeroException:试图除以零。在C:\ users \ administrator \ documents \ TestExceptionNesting \ TestExceptionNesting.cs:line 22中的TestExceptionNesting.Program.Main(String [] args)
C:\ users \ administrator \ documents \ TestExceptionNesting \ bin \ release>
我今天在一次面试中被问到这个问题,面试官一直回头说:“你确定最后没有被打来吗?” 我不确定这是否是一个棘手的问题,或者面试官是否还有其他想法,并为我编写了错误的代码来进行调试,所以我回到家尝试了一下(构建和运行,没有调试器交互),只是想着想休息。
使用C#控制台应用程序进行测试,在引发异常之后,将执行finally代码:存在“应用程序错误对话框”,并且在选择“关闭程序”选项之后,在该控制台窗口中执行了finally块。但是将断点设置在finally代码块中,我永远无法实现。调试器不断在throw语句处停止。这是我的测试代码:
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