标准IDispose模式浅析
DoNet资源
众所周知,.Net内存管理分托管资源和非托管资源,把内存中的对象按照这两种资源划分,然后由GC负责回收托管资源(Managed Resource),而对于非托管资源来讲,就需要程序员手动释放。
Framework的设计者的本意是降低Developer的入门难度,提高开发效率,让使用者更少的关注“垃圾回收”,但也正是如此的封装,才导致越来越多的滥用,甚至可怕的效率低下。(这里,我本人强调的是对DoNet垃圾回收机制的理解程度导致的滥用现象。)常常有人抱怨资源一直没有被回收,或者没有按照时间点回收,或者创建再生资源时,效率低下。(“再生资源”指刚刚被完全释放的资源,依据《.Net设计规范》中的说法,不适当的回收导致在创建时的效率低下。)
说了这些就是想提醒大家,我们要有一个更正确,更完善的方式回收资源。
IDisposable接口
在Framework的设计中很多地方都实现了IDisposable接口的Dispose方法,GC会自动地,随机地调用某个资源的析构方法,从而达到自动回收垃圾的目的,该接口来自于System命名空间下。
所以,对于我们自定义的类来讲一般都要实现IDisposable接口,已完成自动回收。
标准IDispose模式
不罗嗦了,网上相关的资料很多,这里写下来也是让自己更熟悉这种模式,毕竟理解是一回事,讲解出来又是另一回事。
首先引用IDisposable接口,然后,没有然后了,直接贴代码:
#region 标准IDispose模式 Private bool disposed = false; Public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~XXXXClass() { Dispose(false); } Protected virtual void Dispose(bool disposing) { If(disposed) Return; If(disposing) { If(Resource != null) { // Release managed resource } } // Release unmanaged resource disposed = true; } #endregion
- GC.SuppressFinalize(this); 这个方法是告诉GC一个对象已经手动释放过,并且不需要再释放了,这样的话,对象能被更早的再生。一般是紧跟在Dispose(true)之后。
- ~XXXXClass()析构函数,函数释放时自动执行。其中Dispose(false)程序自动调用时,只回收非托管资源。
- Protected virtual void Dispose(bool disposing) 标识为 Protect 是为了更好的封装,virtual是便于继承类重写。
- 对于某些资源的释放要做如下三部:
a) A != null如果为空的话,不用释放。
b) A.Dispose();
c) A == null;
- GC回收资源是靠将资源标记成(Generate)代的概念,0代则直接回收,1代减一变成0代,2代回收时减一变成1代。
- GC.Collect()就是手动将资源标记的方法,但是即使是0代也未必立即回收释放。
Reference
《.Net设计规范》(Framework Design Guideline)
http://msdn.microsoft.com/zh-cn/library/System.GC(v=vs.80).aspx
工程狮必备属性:追新,执着,高内聚低耦合。
版权声明:凡是没有标注[转载]的,在引用文章时,均要加上本博客地址,谢谢。
http://www.cnblogs.com/cuiyansong/。