VB.NET中Finalize与Dispose的区别


本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议 进行许可。

在VB.NET框架中,类没有真正意义的析构函数,但是有两种方式可以实现析构函数功能一个是Finalize方法,用于被动的释放资源;另一个dispose方法,可以主动的释放资源。


Finalize方法垃圾回收系统(GC)自动调用。使用Finalize方法需要注意以下要点:

1. 延迟调用特性
由于垃圾回收是由.NET框架通过一个独立的线程自动调用的,因此当所有指向对象的变量都设置为nothing之后,Finalize方法不会立即被调用

2. 访问限制
一方面,托管对象的资源释放是由垃圾回收系统完成的,在Finalize方法中不必管理其它托管对象的释放工作;另一方面,也不要在Finalize方法中访问任何托管对象,因为这些托管对象很可能已经被销毁。在Finalize方法中应该总是释放那些非托管对象(如文件句柄等)的资源。

3. 调用限制
永远不要在程序中主动调用Finalize方法调用Finalize方法的唯一方式是将引用对象的变量设置为nothing


由于Finalize方法的种种限制,特别是延迟调用特性,我们不得不使用一种更主动的方式来释放资源,那就是实现Idisposable.dispose方法。使用dispose方法需要注意以下要点:

1. 立即执行
与Finalize的延迟调用特性不同,dispose方法被设计成使用者主动调用并立即执行。这是一种可控制的释放资源的方法

2. 托管资源的释放
除了非托管对象的释放工作之外,dispose还要负责托管对象的释放(注释1) ,这一点Finalize方法是做不到的。

3. 调用不受限制
程序中可以多次调用对象的dispose方法。通常情况下,只有第一次调用时释放资源。


如何选择释放资源的方法呢?是实现Finalize还是实现dispose?

如果不介意延迟调用并且对象内部仅有非托管资源需要释放,实现Finalize方法是很好的选择。选择Finalize方法完全取决于我们对延迟调用的容忍程度,试问当我们想要关闭一个文件时系统却没有及时响应,这样的情况是否允许?

如果对象内部存在其它托管对象并且这些托管对象实现了dispose方法,那么实现dispose方法用于释放内部的托管对象将是唯一的选择。因为只有在dispose方法中才可以调用其内部对象的dispose方法

如果要实现的类是一个基类,并且不想让继承类的释放过程过于复杂,请使用dispose-Finalize模式实现释放资源的功能

注释1:释放托管对象的资源


有两个方法可以释放托管对象的资源:如果托管对象实现了Idisposable.dispose方法调用这个方法;然后将指向托管对象的变量设置为nothing。可以用下面的方法一站式处理:

© 丑小鸭技术专栏 | 查看原文

相关文章

Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强...
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办...
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace...
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用...
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选...
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As Dat...