2010-09-29 77 views
4
try 
{ 
    try 
    { 
     throw new Exception("From Try"); 
    } 
    catch 
    { 
     throw new Exception("From Catch"); 
    } 
    finally 
    { 
     throw new Exception("From Finally"); 
    } 
} 
catch (Exception ex) 
{ 
    Console.WriteLine(ex.Message); 
} 

上述代码的输出是:From Finallythrow-catch逻辑

为什么不是From Catch

- 或 -

我怎么能赶上&日志从两个例外之外?

+0

整蛊......期待看到这个答案。 – riwalk 2010-09-29 22:33:02

回答

0

终于总是跑;它总是最后运行。因此,由内尝试做的事情LAT是终于和扔东西,是由外键锁

不知道我理解这个问题

+0

请注意,finally块不*总是运行。有很多情况下finally块不能运行。 (例如,如果尝试包含“快速失败”。) – 2010-09-29 23:39:56

+0

@eric'快速失败'是什么意思 – pm100 2010-09-30 00:04:52

+0

这意味着你失败很快。而不是缓慢地失败。也就是说,当出现问题时,立即停止所有事情*,这样你就不会做任何事情*更糟糕*。如果失败缓慢,您在哪里记录失败并尝试关闭文件并保存用户数据,等等等等可能是个好主意。另一方面,在敲打一万升布丁之前停止机器人手臂可能比花费几毫秒试图恢复更好。如果你在finally块中快速失败,没有其他finally块会运行。该过程只是立即失败。 – 2010-09-30 04:41:10

0

finally的第2部分恰好不管抓到。无论尝试还是捕捉中都有例外。因此,你会看到“From Finally”。 (这实际上是finally条款的整个目的所以,你可以在把代码那里,将清理资源等,不管是什么 - 。即使有一个例外)

6

因为finally块执行之后 catch块,覆盖异常。

而在处理较早的异常时发生异常,第一个异常会丢失。

我该如何捕获&这两个例外之外的日志?

  1. 通过在finally块抛出。这总是一个糟糕的主意。
  2. 如果要登录内部catch块,请使用throw;或将第一个异常作为新异常传递给InnerException。这就是为什么InnerException存在。
+0

当然,我并不是在finally块中自己抛出异常,在finally块中释放资源时抛出异常,这是一种正常行为,我希望被告知有异常,并且与我想要的不冲突“From Catch”例外。 – DxCK 2010-09-29 23:15:44

+0

@dxck,这不正常。资源释放代码通常不应该抛出。你有一个具体的例子吗? – 2010-09-29 23:20:52

+0

例如:写入临时文件失败,因为磁盘空间不足,然后在finally块中我想删除该文件,但由于IO错误或某人与该文件混淆(例如磁盘清理程序)而失败。 – DxCK 2010-09-29 23:29:44

0

你的代码抛出从的try/catch/finally语句的每个部分异常。当您创建新错误时,您实质上是在吞噬以前的异常。你可以添加一些你的“从尝试”消息到你的“从抓”的消息像

catch(Exception ex) 
{ 
    throw new Exception(ex.Message + ":" + "From Catch"); 
} 

我不知道怎么知道你能链,在最后虽然。

0

因为finally块总是被执行。

try 
{ 
    try 
    { 
     throw new Exception("From Try"); 
     // (1) A new exception object A is created here and thrown. 
    } 
    catch // (2) Exception object A is catched. 
    { 
     throw new Exception("From Catch"); 
     // (3) A new exception object B is created here and thrown. 
    } 
    finally // (4) Execution is forced to continue here! 
    { 
     throw new Exception("From Finally"); 
     // (5) A new exception object C is created here and thrown. 
    } 
} 
catch (Exception ex) // (6) Exception object C is catched. 
{ 
    Console.WriteLine(ex.Message); 
} 

步骤(3)和(5)中的每个new'd异常对象都会丢弃前一个。由于finally块总是被执行,所以剩下的就是来自步骤(5)的异常对象C.

3

这是C#语言规范定义的行为。处理在try块内抛出的异常将中止,而在finally块中抛出的异常将被处理。

相关栏目8.9。5 throw语句解释例外是如何传播:

  • 在当前函数成员中,每个try声明封闭着引发点进行检查。对于每个语句S,从最里面的try发言,并与最try发言结束,对下列步骤进行计算:

    • 如果S try块封闭着引发点,如果S有一个或多个catch子句,catch子句按外观顺序进行检查,为异常找到合适的处理程序。指定异常类型或异常类型的基本类型的第一个catch子句被认为是匹配的。一般的catch子句(§8.10)被认为是任何异常类型的匹配。如果找到匹配的catch子句,则通过将控制转移到该catch子句的块来完成异常传播。

    • 否则,如果块tryS一个catch块封闭着引发点,并且如果S具有finally块,控制被转移到最终块。 如果finally块引发另一个异常,则终止当前异常的处理。否则,当控制权到达finally块的终点时,继续处理当前异常。

0

这是一个非常好的问题,一个是棘手的一种。让我们通过这一步一步:

try 
{ 
    throw new Exception("From Try"); 
} 
catch 
{ 
    throw new Exception("From Catch"); 
} 

在上面的代码,异常(“从尝试”)抛出并由catch子句(很简单至今)抓获。该catch子句抛出它自己的,通常我们会想到(因为捕捉嵌套在一个更大的try-catch块)将被立即引起了一个例外,但...

finally 
{ 
    throw new Exception("From Finally"); 
} 

的最终条款,这保证(尝试)执行,先到达并抛出它自己的异常,覆盖之前抛出的异常(“从Catch”)

“抓的常见用法,最后 在一起是为了获得在try块使用 资源,在catch 块处理 特殊情况下,并在 释放资源finally块” - MSDN Article

遵循这个逻辑逻辑,我们应该尽力避免在我们的catch中编写代码,并最终阻止那些容易出现异常的块。如果您担心出现问题,我建议您将异常及其相关信息记录到外部文件中,您可以参考该文件进行调试。

1

添加的try-catch块额外的一层类似如下:

try { 
    Exception fromCatch = null; 
    try { 
     throw new Exception("From Try"); 
    } 
    catch { 
     try { 
      throw new Exception("From Catch"); 
     } 
     catch (Exception e) { 
      // catch failed -> store exception 
      fromCatch = e; 
     } 
    } 
    finally { 
     try { 
      throw new Exception("From Finally"); 
     } 
     catch (Exception e) { 
      // i can think of better exception merging... but this shows the idea 
      throw new Exception(e.Message, fromCatch); 
     } 
     // throw fromCatch, in case "From Finally did not happen" 
     throw fromCatch; 
    } 
} 
catch (Exception ex) { 
    Console.WriteLine(ex.Message); 
    if (ex.InnerException != null) { 
     Console.WriteLine(ex.InnerException.Message); 
    } 
} 

报告:

From Finally 
From Catch 

编辑:这显然是问题的两个答案,如 “为什么” 是充分回答:)