【发布时间】:2017-12-03 09:22:15
【问题描述】:
来自实现 Finalize 的 MSDN 文章;
对于使用非托管资源(例如文件句柄或数据库连接)的类,您应该重写 Finalize,当使用它们的托管对象在垃圾回收期间被丢弃时必须释放这些资源。
来自实现 IDisposible.Dispose 的 MSDN 文章;
使用此方法关闭或释放实现此接口的类的实例所持有的非托管资源,例如文件、流和句柄。按照惯例,此方法用于与释放对象持有的资源或准备对象以供重用相关的所有任务。
即使在每篇(详尽的)文章的上下文中,这似乎也是一个非常模棱两可的定义。
我真正失去 Finalize 目的的地方是这里;
因为垃圾收集是非确定性的,所以您无法准确知道垃圾收集器何时执行终结。要立即释放资源,还可以选择实现 dispose 模式和 IDisposable 接口。 您的类的使用者可以调用 IDisposable.Dispose 实现以释放非托管资源,并且您可以使用 Finalize 方法在未调用 Dispose 方法的情况下释放非托管资源。
我是否应该同时实现两者,并在消费应用程序忘记处置我的对象时强制自己完成?
与 GC 如此密切地打交道对我来说是新的……我想确保我正确地放弃了我的资源。但是,我不完全理解为什么这两种都存在,或者何时使用每一种。
【问题讨论】:
-
第一句话说“你应该为使用 非托管 资源的类重写 Finalize”。因此,如果您没有任何非托管资源,则不要覆盖 Finalize。
-
如果消费应用程序忘记释放你的资源,这是他们的问题。 GC 收集可能会立即发生,也可能会在 5 分钟后发生。 Dispose 在同一个线程上运行的目标是尽快释放资源(比如说文件句柄),以便其他人可以使用它。
-
@user3185569 GC 不处理非托管资源。 根据定义确实如此。非托管资源的定义是不被GC管理的资源。
-
通常您会覆盖终结器,以便它调用 Dispose。实现 Dispose 的默认模板说明了这一点,并在方法中提供有关终结器或用户代码是否触发了 dispose 方法的信息。此外,Dispose 方法是确定性的,而您永远不知道何时调用终结器...
-
您实际上有哪些非托管资源需要处理?
标签: c# garbage-collection resources dispose finalize