VB.NET中Finalize与Dispose的区别

Creative Commons License
本作品采用知识共享署名-非商业性使用-相同方式共享 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。可以用下面的方法一站式处理:

 

 

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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值