微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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。可以用下面的方法一站式处理:

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

原文地址:https://www.jb51.cc/vb/261538.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐