根据如何使用IDisposable的模式,Microsoft建议使用finalize来释放非托管源。 http://msdn.microsoft.com/en-us/library/system.idisposable%28v=VS.80%29.aspx
但是如果我们编写一些代码来在最终版本中发布托管源代码会怎样? 也就是说当GC调用最终确定释放一些托管源时,会发生什么?
答案 0 :(得分:3)
一般来说是一种不好的做法。在终结器代码中,您不能依赖于对象的状态及其受管资源 - 它们可以被收集或处理/最终确定。此外,您不能依赖CLR调用Finalize
的订单。
答案 1 :(得分:1)
通常,使用Finalize
清理外部受管资源是没用的,可能很危险。当对象终结器运行时,它所拥有的托管资源可能是:
在某些情况下,让终结器在其他托管对象上调用清理代码可能会有所帮助,但这种调用通常仅适用于对象了解彼此内部详细信息的情况,并且通常应使用{ {1}}或protected
方法,或使用私下交换的代理。例如,在某些情况下,可能存在两个或多个彼此了解的对象,并且具有必须以特定顺序运行的终结器。
例如,可能有一个类的目的是将数据发送到USB设备,另一个类的目的是控制连接到该设备的设备。如果后一类想要确定设备接收到“关闭”命令,则在USB连接类终结器关闭连接之前,其终结器可能需要发送命令。处理这个问题最干净的方法可能是让USB连接对象的构造函数接受它将从其终结器调用的回调。如果班级没有这样的功能,事情就会变得相当棘手。另一种方法可能是让一个对象与包装器分开,它包含清理所需的所有信息,以及包装器对象的internal
,并且有一个timer-tick事件,如果WeakReference
将执行清理已经死了。如果计时器绑定到创建包装器对象的线程,那么即使放弃了包装器对象,也可以允许执行清理,前提是线程仍处于活动状态(如果它可能不存在,事情会变得更复杂)。
答案 2 :(得分:0)
看看这个链接,你可以使用Finalize
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.71).aspx
答案 3 :(得分:0)
为什么(或更好,如何)发布在终结器中管理的内容?当前对象拥有的所有内容此时已被视为垃圾,并将在下一次垃圾收集器中收集。当前不拥有的所有内容都无法释放,因为其他内容可能仍会引用它。
答案 4 :(得分:-1)
无需为托管代码编写Dispose / Finalize。 bcz当对象不再被引用时它将被CLR删除。 Dispose方法是针对非托管代码编写的,如文件处理程序或数据库命令。