.NET框架自动内存管理(6)

.NET框架自动内存管理(6)

 

 

 

 

在上述代码示例中,DisposeBase是可以在应用程序中直接使用的抽象基类,它提供了dispose模式清理非托管资源的基本框架。基类DisposeBase实现IDisposable接口,提供由应用程序调用的公共Dispose()方法,注意该方法是不能由派生类重写的非虚方法,以简化派生类的dispose模式设计。该方法通过调用受保护的virtual Dispose(bool disposing)虚方法执行派生类中实际的资源清理代码。

基类DisposeBase的公共Dispose()方法还调用GC.SuppressFinalize方法以阻止垃圾回收器调用其Finalize方法。因为Dispose()方法已完成了清理对象的实际工作,垃圾回收器就不必调用对象的Finalize方法了,从而保证了应用程序的性能。

基类DisposeBase提供的Finalize方法在应用程序没有调用Dispose()方法的情况下由垃圾回收器自动调用,保证非托管资源最终能够得到释放。它是资源释放的最后一道防护措施。Finalize方法同样通过调用受保护的virtual Dispose(bool disposing)虚方法执行派生类中实际的资源清理代码。这是必要的,它不仅优化了代码的可读性和可维护性,而且还保证了实际的资源清理工作得以执行。

受保护的virtual Dispose(bool disposing)虚方法通过参数disposing指示以两种截然不同的方案执行。如果disposing参数为true,则该方法由应用程序直接或间接调用,这时垃圾回收器被阻止调用其对象的Finalize方法,因此托管资源和非托管资源都必须被清理;如果disposing参数为false,则该方法由垃圾回收器从Finalize方法内部调用,这时只能清理非托管资源。因为垃圾回收器执行对象的Finalize方法的顺序是不确定的,所以在对象的Finalize方法内部不应引用其他对象。如果正在执行的Finalize方法引用了另一个已终止的对象,则该Finalize方法将执行失败。

由于实际的资源清理工作由派生类实现,所以基类DisposeBasevirtual Dispose(bool disposing)虚方法不执行任何操作。

派生类ResourceWrapper则阐释了如何从实现资源管理的基类继承并实现实际的资源清理工作。ResourceWrapper重写了Dispose(bool disposing)方法并提供托管和非托管资源的清理代码,以完成实际的资源清理工作。私有成员变量disposed确保了即使多次调用Dispose()方法,实质的资源清理工作也只执行一次,避免了重复进行资源释放引发的错误。

在派生类重写的Dispose(bool disposing)方法中还调用了基类的Dispose(bool disposing)方法以确保基类能够适当地清理资源。

派生类还提供了一个与Dispose()等效的Close()方法,因为对于某些非托管资源(例如流资源或网络连接),“关闭”比“处置”在语义上更贴切。注意Close方法内部不应重建清理资源的代码而应直接调用Dispose()方法。

dispose模式的上述实现方案中,派生类ResourceWrapper不再需要提供Dispose()Finalize方法,因为虚函数的多态性决定了调用基类的Dispose()Finalize方法能够正确的执行资源清理操作。

以上只是dispose模式实现的一种可能方案,但这不是唯一的方案。只要遵循dispose模式的原则,dispose模式可以有很多种实现方案。例如,在FCL中封装非托管资源的类(例如GDI+中的类以及Stream类等)就使用了一种很不相同的dispose模式实现。但是在上述方案中,基类提供了dispose模式框架,并且可以直接编译并在应用程序中复用。派生类只需要简单的重写带参数的受保护Dispose(bool disposing)虚方法,除此之外并没有太多的涉及资源清理的代码。因此它不失为一种值得推荐的比较简洁的dispose模式实现方案,它并没有给应用程序开发者带来太多的额外编码工作,应用程序开发者甚至可以不必要了解dispose模式和垃圾回收器如何调用Finalize方法就可以编写出正确的实现资源清理的代码。

最后提醒一下,使用封装了非托管资源(例如磁盘I/O操作、网络连接、数据库连接等)的对象时,应及时调用DisposeClose方法清理这些非托管资源,使得这些资源不会成为系统性能的瓶颈,而不要依赖于垃圾回收器。垃圾回收器只能是你的最后屏障。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值