引发异常时Catch块的行为

本文关键字:Catch 异常 | 更新日期: 2023-09-27 18:28:10

是否存在引发异常时跳过catch块的情况比如

try 
{
  some code
}
catch(Exception ex)
{
  some code
}

我正在使用Exception类,因为它捕获了所有的Exception。

引发异常时Catch块的行为

您可能有StackOverflowException问题(请参阅CAN';T在.NET中捕获的异常列表)

还有另一类情况,特别是当抛出的东西不是Exception时,但这只是当你在1.1中,或者没有启用自动异常包装(默认情况下从2.0开始启用)时——理论上C++可以抛出任何东西(而不仅仅是Exception),所以如果你的"一些代码"调用一些C++,一个string,那么在理论上你可能会错过它。

事实上,这很少(如果有的话)是一个真正的问题:

  • 默认情况下启用自动换行
  • 大多数与.NET对话的C++代码都认为Exception(或子类)表现良好

在这种情况下,catch { ... }会拦截抛出的东西,但不会告诉您发生了什么。

所有异常都将Exception作为基类型。如果try块中的代码导致异常,则会导致执行匹配类型的catch块中的码。如果您还有一个更具体的catch块匹配,那么该块将被执行:

try
{
    throw new FileNotFoundException();
}
catch (FileNotFoundException)
{
    // this code will run
}
catch (Exception)
{
    // this won't (but will if a different exception is thrown)
}

如果catch块中的代码导致Exception,它将离开catch块并找到匹配的"父"catch块。

请注意,只有当前线程上的异常才会被捕获——如果您在try块中启动并等待异步操作,则可能无法在等待的线程上捕获它们。

正如Marc所指出的,有一些异常是无法捕获的,例如StackOverflowException。

在.NET 4中,存在损坏状态异常的概念,以指示除非代码明确表示有兴趣处理这些异常,否则不会传递给托管代码的异常。这些异常(例如AccessVoilationException)表示严重的编程错误,通常不能保证发生时内存/程序状态的一致性。有关更多信息,请参阅这篇精彩的文章:http://msdn.microsoft.com/en-us/magazine/dd419661.aspx

如果CLR出现异常(如堆栈溢出),它将不会捕获该异常。

但对于正常的例外情况,你会发现一切。

它不应该跳过,因为所有异常都是从Exception类派生的。你有没有遇到过另一种情况?

try  
{   
    //some code 
} 
catch(System.DivideByZeroException dbz)
{
    //Divide by Zero exception catched
}
catch(Exception ex) 
{   
    //some code 
} 

您已经给出了Exception类,它是所有异常的基类。因此,您需要给出特定的Exception类,如ArgumentNotFoundException。

如果您不想捕捉任何异常,请将其留空。但请记住,使用Try..Catch块会占用大量资源,因此只有在确定可能发生何种异常的情况下,才建议使用它。