为什么即使使用using语句也不会调用Dispose?

Ka *_*ius 2 c# dispose

我有这个控制台应用程序(.NET Framework 4.5.2):

class Program
{
    static void Main(string[] args)
    {
        using (var result = new Result())
        {
            result.Test();
        }
    }
}

public class Result : IDisposable
{
    public void Test()
    {
        int a = 1;
        int b = 1 / (a - 1);
    }

    public void Dispose()
    {
        Console.WriteLine("Dispose");
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么Dispose不调用方法?DisposeDivideByZero-exception 之后没有输入断点,并且控制台上没有输出(因为应用程序退出).

Mic*_*han 7

根据MS Docs:try-finally(C#参考)

在处理的异常中,保证运行关联的finally块.但是,如果未处理异常,则finally块的执行取决于如何触发异常展开操作.反过来,这取决于您的计算机的设置方式.

由于您没有捕获DivideByZero异常并且未对其进行处理,因此在您的计算机和设置上,它必须在运行任何其他代码行之前关闭应用程序,因此不会运行该finally块.

正如@Evk在下面的注释中指出的那样,如果我在没有附加调试器的情况下运行它,它会正确解开异常并执行finally块.每天学些新东西.

根据Eric Lippert对Finally Block Not Running的回答?

想想这种情况有多糟糕:发生了意想不到的事情,没有人编写代码来处理.在这种情况下做正确的事情是运行更多的代码,这可能也不是为了处理这种情况而构建的?可能不是.通常,在这里做的正确的事情是不要尝试运行finally块,因为这样做会使情况更糟.你已经知道这个过程正在下降; 立刻摆脱痛苦.

在未处理的异常将取消该过程的情况下,任何事情都可能发生.它是实现定义的,在这种情况下会发生什么:是否向Windows错误报告报告错误,是否启动调试器,等等.CLR完全有权尝试运行finally块,并且完全在其快速失败的权利范围内.在这种情况下,所有赌注都已关闭; 不同的实现可以选择做不同的事情.

  • OP也更有可能在调试器下运行应用程序,在这种情况下,VS将终止未处理异常的进程(不会解除它).如果OP在同一台机器和配置上没有调试器运行 - 它将执行finally块. (2认同)
  • 据我所知 - Visual Studio 调试器总是在未处理的异常后“杀死”进程,不知道是否有任何方法可以避免这种情况。例如,您可以使用“Environment.FailFast”来模拟相同的情况。如果你做`try { ...一些东西...; Environment.FailFast("some message");} finally {}` then finally 块即使没有调试器也不会运行。或者您可以从任务管理器中终止进程。 (2认同)