为什么即使在使用状态下也不调用Dispose? [英] Why Dispose is not called even with using-statement?

查看:52
本文介绍了为什么即使在使用状态下也不调用Dispose?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have this console application (.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");
    }
}

为什么处置方法没有调用?在 DivideByZero 例外之后,在 Dispose 中没有断点,并且控制台上没有输出(因为该应用程序

Why Dispose method is not called? A breakpoint is not hit in Dispose after the DivideByZero-exception and there is no output on the console (because the app exits).

推荐答案

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

As per MS Docs: try-finally (C# Reference)


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

Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up.

因为您没有抓住 DivideByZero 异常,并使其在您的计算机上进行处理并进行设置,必须先关闭应用程序,然后再运行其他任何代码行,因此不运行 finally 块。

As you are not catching the DivideByZero exception and let it be unhandled, on your machine and setup it must be bringing down the application before any other line of code is run and therefore not running the finally block.

正如@Evk在下面的注释中指出的那样,如果我在不附加调试器的情况下运行它,则会消除异常正确并执行finally块。每天学习新知识。

As @Evk has pointed out in below comment, if I run it without attaching debugger, it unwinds the exceptions correctly and executes the finally block. Learn something new everyday.

根据 Eric Lippert对最终阻止不运行的回答


想想这种情况有多糟糕:
发生了意外情况,没人写过代码处理。
在这种情况下执行正确的操作以运行更多代码是否正确,那可能不是
为处理这种情况而构建的吗?可能不是。
在这里经常做的正确的事情是不要尝试运行finally块,因为这样做
会使情况更糟。您已经知道该过程正在减少

Think about how awful that situation is: something unexpected has happened that no one ever wrote code to handle. Is the right thing to do in that situation to run even more code, that was probably also not built to handle this situation? Possibly not. Often the right thing to do here is to not attempt to run the finally blocks because doing so will make a bad situation even worse. You already know the process is going down; put it out of its misery immediately.

在一个未处理的异常将使
流程崩溃的情况下,任何事情都可能发生。这是由实现定义的,在这种情况下
会发生什么:是否将错误报告给Windows错误
报告,调试器是否启动等等。 CLR在尝试运行finally块的权限内完全处于
的范围内,并且在
的范围内也具有快速运行失败的权限。在这种情况下,所有
的赌注都关闭;不同的实现可以选择做
的不同事情。

In a scenario where an unhandled exception is going to take down the process, anything can happen. It is implementation-defined what happens in this case: whether the error is reported to Windows error reporting, whether a debugger starts up, and so on. The CLR is perfectly within its rights to attempt to run finally blocks, and is also perfectly within its rights to fail fast. In this scenario all bets are off; different implementations can choose to do different things.

这篇关于为什么即使在使用状态下也不调用Dispose?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆