catch 和finally 中抛出异常。 CLR 行为与 try-catch 块[重复]

2024-03-20

我编写了简单的 C# 控制台应用程序:

class Mystery
{
    static void Main(string[] args)
    {
        MakeMess();
    }

    private static void MakeMess()
    {
        try
        {
            System.Console.WriteLine("try");
            throw new Exception(); // let's invoke catch
        }
        catch(Exception)
        {
            System.Console.WriteLine("catch");
            throw new Exception("A");
        }
        finally
        {
            System.Console.WriteLine("finally");
            throw new Exception("B");
        }
    }
}

控制台中给出的输出是:

try

catch

未处理的异常:System.Exception:A at Mystery.Program.MakeMess() in ...

看来CLR抓住了A并且finally 块根本没有被调用。

但是当我用 try-catch 块包围对 MakeMess() 的调用时:

static void Main(string[] args)
{
    try
    {
        MakeMess();
    }
    catch(Exception ex)
    {
        System.Console.WriteLine("Main caught " + ex.Message);
    }
}

输出看起来完全不同:

try

catch

finally

主要抓B

当 Exception 在方法外部严格处理时,从 MakeMess() 传播的 Exception 似乎有所不同。

这种行为的解释是什么?


您所看到的行为与finally是否投掷块。您的应用程序中只是有一个未处理的异常,当这种情况发生时,所有的赌注都会被取消,包括如果finally块运行与否:

From MSDN https://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx文档:

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

通常,当未处理的异常结束应用程序时,是否运行finally 块并不重要。但是,如果finally 块中的语句即使在这种情况下也必须运行,一种解决方案是向try-finally 语句添加catch 块。或者,您可以捕获可能在调用堆栈上方的 try-finally 语句的 try 块中引发的异常。也就是说,您可以在调用包含 try-finally 语句的方法的方法中捕获异常,或者在调用该方法的方法中捕获异常,或者在调用堆栈中的任何方法中捕获异常。如果异常没有被捕获,finally 块的执行取决于操作系统是否选择触发异常展开操作。

如果finally块mustrun,那么解决方案就是精确执行第二个片段中所做的操作:处理未处理的异常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

catch 和finally 中抛出异常。 CLR 行为与 try-catch 块[重复] 的相关文章