24

为什么不是 "Console.WriteLine("asdf");" 行 执行?其他都是。不应该也是因为我们不能从finally范围中跳出来吗?

static bool Func()
{
    try
    {
        try
        {
        }
        finally
        {
            try
            {
                throw new ApplicationException();
            }
            finally
            {
                Console.WriteLine("asd");
            }

            Console.WriteLine("asdf");
        }
    }
    finally
    {
        Console.WriteLine("asd");
    }
}
4

7 回答 7

30

finally 块仅保证(至少大部分保证,请参阅下面的 MSDN 摘录)在 try 块引发异常的情况下将输入它们。如果finally 块中抛出异常,该异常将导致控制权离开 finally 块,并且该 finally 块中的其余代码将不会执行。

在您的情况下,未执行的行发生在同一个 finally 块中的异常之后,因此它被跳过。

来自MSDN - try-finally

finally块可用于清理在try块中分配的任何资源,以及运行任何必须执行的代码,即使在try块中发生异常也是如此。通常,finally块的语句在控制离开try 语句时执行,无论控制转移是由于正常执行、执行breakcontinuegotoreturn 语句,还是传播异常而发生出try语句。

在已处理的异常中,保证运行关联的finally块。但是,如果异常未处理, finally块的执行取决于异常展开操作的触发方式。反过来,这取决于您的计算机的设置方式。有关详细信息,请参阅 CLR 中的未处理异常处理。

注意:CLR 中的未处理异常处理是对 MSDN 杂志 2008 年 9 月号中的一篇文章的引用。所有 2008 年及更早版本的 MSDN 杂志仅以 .chm 文件的形式提供,需要在查看前下载。

于 2012-06-14T18:59:04.590 回答
19

我认为可以回答这个问题的最好方法是使用代码,因此使用下图 在此处输入图像描述

于 2012-06-14T19:15:04.887 回答
6

因为在该 finally 块中引发了异常,所以它导致控制权落到最终的 finally 块中。所以“asdf”WriteLine 永远不会执行。

于 2012-06-14T18:59:30.217 回答
4

在finally(或catch)块中抛出的异常会取消该finally(或catch)块的其余部分。

于 2012-06-14T18:59:02.077 回答
3

错误发生在第三个 try 块内,导致其相应的 finally 被执行。但是,这会导致它从当前的 finally 中出错并被原始的 try-finally 块捕获。

于 2012-06-14T19:01:05.477 回答
1

因为你已经抛出了 try 块,它会执行 finally 块Console.WriteLine("asd");并退出到外部 try catch

于 2012-06-14T19:02:22.390 回答
-1

当我在跨不同主机平台部署的代码上使用 try-finally 块时,我发现:当 try 块上没有引发异常时。

一些 Windows 平台总是执行 finally 块,而一些平台从不执行 finally 块。

我的 finally 块包含关闭错误日志的指令,并且无法执行 finally 块总是在退出时引发另一个异常,只留下密码信息来找出导致错误的原因。对于我的应用程序,try finally 块比它们的价值更麻烦。

于 2014-04-15T10:12:35.117 回答