繁体   English   中英

在 .NET 中,如果 catch 块中出现故障,最终总是会被调用怎么办?

[英]In .NET, what if something fails in the catch block, will finally always get called?

在 try/catch/finally 块中,例如:

try
{

}
catch()
{
   // code fails here
}
finally
{ 

}

那么如果catch块中有异常,最终总是会被调用吗?

如果没有 finally,catch 块之后的代码会运行吗?

假设进程不会突然终止(当然也不会挂起),finally 块将始终被执行。

如果没有 finally 块,catch 块中的异常将被抛出堆栈。 请注意,最初导致 catch 块执行的原始异常将被有效地丢失。

堆栈溢出异常

正如 Jared 所指出的,堆栈溢出将导致 finally 块不被执行。 我相信这会突然终止程序,但我可能是错的。 这是示例代码:

using System;

public class Test
{    
    static void Main()
    {
        // Give the stack something to munch on
        int x = 10;
        try
        {
            Main();
            Console.WriteLine(x);
        }
        finally
        {
            Console.WriteLine("Finally");
        }
    }  
}

结果:

进程因 StackOverflowException 而终止。

finally 块将始终被执行。 如果您排除 finally 块,并且在 catch 块内发生异常,则 catch 块之后不会执行任何代码,因为本质上您的 catch 块将失败并自身生成未处理的异常。

是的,finally 将永远运行

不,catch 块之后的代码将不会运行。

即使使用 finally 块,finally 块之后的任何代码都不会运行。

如果 catch 块中有异常,finally 会执行,但是会抛出一个新的异常。 发生异常的 catch 块不会捕获异常,它会继续向上堆栈。

经验教训:如果你能帮助它,不要在 catch 块中做可以抛出的东西; 如果必须,请嵌套一个 try/catch 块。

try
{

}
catch()
{
  try
  {
    // code fails here
  }
  catch
  {
    // handle that. Or not. 
  }
}
finally
{ 

}

finally 块将始终被执行。 来自MSDN

finally 块对于清理在 try 块中分配的任何资源以及运行任何必须执行的代码(即使存在异常)也很有用。 不管 try 块如何退出,控制总是传递给 finally 块。

catch 用于处理语句块中发生的异常,而 finally 用于保证语句块的执行,而不管前面的 try 块如何退出。

顺便说一句,这是您可以通过编写一些代码、编译它并查看执行它时发生的情况来轻松测试自己的问题类型。

class Program {
    static void Main(string[] args) {
        try {
            Console.WriteLine("Trying!");
            throw new Exception();
        }
        catch (Exception e) {
            Console.WriteLine("Catching {0}!", e.Message);
            throw new Exception();
        }
        finally {
            Console.WriteLine("Finally!");
        }
    }
}

这输出:

Trying!
Catching Exception of type 'System.Exception' was thrown.!

Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
at TestFinally.Program.Main(String[] args) in C:\Documents and Settings\Me\My
Documents\Visual Studio 2008\Projects\TestFinally\TestFinally\Program.cs:line 15
Finally!
Press any key to continue. . .

只是想添加我知道的不允许 finally 和任何其他代码块执行的情况:

  • 在运行时抛出 StackOverflowException 的情况下
  • System.Environment.FastFail
  • 环境.退出
  • 如果一个“后台”线程因为它所属的主程序正在结束而终止。
  • 意外关机:)

如果 catch 块中发生异常,finally 中的所有代码仍然会被执行。 如果堆栈中有更高的异常处理程序(例如此函数的调用者),它将捕获此异常。 否则会导致未处理的异常并关闭您的应用程序。

catch 块中异常点之后的代码不会被调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM