我最近遇到了一个与在 Finalize 方法重载中运行的代码有关的问题。
我主要了解与内存管理/性能相关的问题,但我很感兴趣是否有任何关于“哪些代码应该/不应该进入 Finalize 方法”的指导方针?
例如:
- 不要从 Finalize 方法中抛出异常。
- 代码应该快速执行。
- 不要引发事件(?)
- ETC...
由于引发了导致某些异常的事件,因此可以看到我的情况。
所以我的问题是——关于最终确定方法,我必须遵循哪些准则(甚至可能使用某些工具强制执行)?
我最近遇到了一个与在 Finalize 方法重载中运行的代码有关的问题。
我主要了解与内存管理/性能相关的问题,但我很感兴趣是否有任何关于“哪些代码应该/不应该进入 Finalize 方法”的指导方针?
例如:
由于引发了导致某些异常的事件,因此可以看到我的情况。
所以我的问题是——关于最终确定方法,我必须遵循哪些准则(甚至可能使用某些工具强制执行)?
最终确定仅用于摆脱非托管资源
来自MSDN
如果 Finalize 或 Finalize 的覆盖引发异常,并且运行时不是由覆盖默认策略的应用程序托管,则运行时将终止进程,并且不会执行任何活动的 try-finally 块或终结器。如果终结器无法释放或销毁资源,此行为可确保进程完整性。
Finalize 操作具有以下限制:
垃圾回收期间终结器执行的确切时间未定义。除非调用 Close 方法或 Dispose 方法,否则不保证在任何特定时间释放资源。
不保证两个对象的终结器以任何特定顺序运行,即使一个对象引用另一个对象。也就是说,如果对象 A 具有对对象 B 的引用并且两者都有终结器,那么当对象 A 的终结器启动时,对象 B 可能已经终结。
运行终结器的线程未指定
你应该没有理由调用finalize。尽管它对您开放,但使用 finalize 的最佳做法是不要使用它们。相反,从 IDisoposable 继承。这不仅是最佳实践,而且不会干扰垃圾收集,并且具有方便的“使用”子句来自动处理。继承这个类也向其他开发者说明这是一个有资源要处理的对象,而我是一个特殊的方式。我什至认为 GC 会在垃圾运行期间调用 dispose。
简而言之,你可以用 finalize 做的任何事情都最好用 dispose 来完成。