在.NET中,finalizers是否有保证会在某个时间点(避免了断电等情况)执行?我知道GC的工作原理,以及它是不确定何时运行的。
(搜索结果没有给出满意的答案,因此我在高度期望与不易发现的实际答案合并时添加了这个问题。除此之外,我已经知道答案,并将在几天后添加它,以防没有人提到它。)
在.NET中,finalizers是否有保证会在某个时间点(避免了断电等情况)执行?我知道GC的工作原理,以及它是不确定何时运行的。
(搜索结果没有给出满意的答案,因此我在高度期望与不易发现的实际答案合并时添加了这个问题。除此之外,我已经知道答案,并将在几天后添加它,以防没有人提到它。)
正如Raymond Chen解释的那样,finalizer可能实际上永远不会被执行。有趣的是这个问题在他的年度CLR周期间被提出,就在他解释之后的两天 :)
如果您想知道是否可以依赖finalizers,那么这已经是您需要了解的全部内容:不要依赖finalizers。
正确编写的程序不能假设finalizers将会执行。
正如Raymond Chen在链接的文章中所述:
Finalizers是一种安全网,而不是资源回收的主要手段。
如果您正在寻找如何释放资源,请查看可处置模式。
例如,finalizer可能不会运行,如果:
(注:时间值可能随时间变化而变化,但在一段时间内肯定是正确的。)
我猜还有很多其他原因会导致finalizer永远不会运行。除了Mr. Chen的引用之外,底线是finalizer是一个安全网,可以减少错误的影响,因为例如资源会在某个时候被释放,这比从未释放要好,如果您忘记明确释放它。
如果 finalizer 抛出异常,其他 finalizer 将不会执行。
如果您在对象上调用 SuppressFinalizer
,也可以禁止 finalizer。
来自 MSDN (Object.Finalize):
在以下异常情况下,Finalize 方法可能无法完成运行或根本不运行:
- 另一个 finalizer 无限期地阻塞(进入无限循环、尝试获取它永远无法获取的锁等)。因为运行时尝试将 finalizer 完全运行,如果 finalizer 无限期地阻塞,则可能不会调用其他 finalizer。
- 进程终止而没有给运行时清理的机会。在这种情况下,运行时的第一个进程终止通知是 DLL_PROCESS_DETACH 通知。