析构函数与IDisposable?

我已经阅读了关于在C#中处理对象/ IDisposable接口和析构函数的问题,但对我来说他们似乎也是这样做的?

两者有什么区别? 为什么我会用另一种呢? 事实上,在这个例子中(下面的链接),这段代码使用了IDisposable接口和析构函数:

http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

评论说,析构函数是如果不使用终结代码,但我该如何决定何时使用终结代码?


我写了一篇相当深入的文章,有助于解释终结器,IDisposable,以及何时应该使用其中一个:http://gregbee.ch/blog/implementing-and-using-the-idisposable-interface

可能最相关的部分引用如下:

在使用非托管资源(如句柄和数据库连接)时,应使用延迟获取和早期发布的原则,确保它们保持最短时间。 在C ++中,释放资源通常是在析构函数中完成的,该析构函数在删除对象时确定运行。 但是,.NET运行时使用垃圾回收器(GC)来清理和回收不再可访问的对象所使用的内存; 因为它定期运行,这意味着你的对象被清理的地方是不确定的。 这样做的结果是,管理对象不存在析构函数,因为没有确定的位置来运行它们。

除了析构函数之外,C#还有终结器,这些终结器是通过覆盖基类Object类中定义的Finalize方法来实现的(尽管C#有些混淆地使用C ++析构函数语法〜Object来实现此目的)。 如果一个对象覆盖Finalize方法,而不是在GC超出范围时被GC收集,则GC将它放在终结器队列中。 在下一个GC循环中,队列中的所有终结器都会运行(在当前实现中的单个线程上),并且回收最终对象中的内存。 这很明显,为什么你不想在终结器中进行清理:它需要两个GC周期来收集对象而不是一个,并且有一个单线程,其中所有终结器都运行,而其他每个线程都被挂起,所以它会损害性能。

因此,如果您没有析构函数,并且不想将清理工作留给终结器,那么唯一的选择是手动确定性地清理对象。 输入IDisposable接口,该接口提供支持该功能的标准,并定义一个方法Dispose,您可以在其中放入对象的清理逻辑。 当在finally块中使用时,此接口为析构函数提供等效的功能。 代码中最后阻塞的原因主​​要是支持IDisposable接口; 这就是为什么C ++使用简单的尝试/除非因为不需要使用析构函数的finally块。


简洁版本

终结者为您提供了处理非托管资源的机会,以防对象的用户忘记调用IDisposable.Dispose

如果您的对象实现了IDisposable ,那么您的对象的用户必须调用.Dispose 。 你不必清理用户的混乱; 但这是一件很好的事情。


我在Stackoverflow上最受欢迎的答案从一开始就让你了解为什么你有IDisposable,它应该做什么,你的终结器可以做什么,它不应该做什么。

这个答案会融化面部

已被用来描述它:P


在托管编程语言中使用析构函数(〜Object())是最为愚蠢的想法。 像C,C ++这样的非托管语言在使用RAII语言时会有析构函数,但像Java,C#这样的管理非常荒谬。

Java Collection Framework的前项目负责人Joshua Bloch指出,Java中finalize()方法(相当于C#的C ++类似析构函数)的想法是有史以来犯下的最大错误。 与C#相同,Java中的finallize()会给“新”带来开销,因为它必须在分配期间添加到finallizer队列中。 此外,垃圾收集器必须在队列中弹出并运行finallize(),因此gc期间的开销是两倍。

C#有许多增强功能,例如“using(IDisposable){}”,它不仅允许将IDisposable变量限制在“using”块的范围内,还可以保证清理。 我的问题是,为什么C#会遵循导致错误的Java相同的路径。 如果dotnet的开发在2003年〜2005年左右开始,当许多Java架构师发现finallize()的谬误时,那么错误就会被阻止。

很多关于一种语言的好主意常常被转移到其他语言,如C#中的“IDisposable / using combo”,它在其“try(object-to-dispose){}”语句中被转移到Java 1.7。 但是它的糟糕之处在于,语言建筑师在从一个人转移到另一个人的过程中,并没有发现这个坏主意被假装为好主意。

如果您需要手动清理非托管资源(如数据库连接),我的建议是绝对不要使用〜Destructor()并坚持使用IDisposable / combo。

链接地址: http://www.djcxy.com/p/54541.html

上一篇: Destructor vs IDisposable?

下一篇: Difference between destructor, dispose and finalize method