IDisposable接口在.net里算是比较简单的接口,也是讨论的比较多的接口之一.下文总结了些自己的个人看法(如有不对之处,敬请拍砖)并引用了部分MSDN和其他博客的文字(如有侵权,请联系我,如若转载,请注明出处,谢谢。)
首先来看MSDN中关于这个接口的说明:
[ComVisible(true)]:指示该托管类型对 COM 是可见的.
- [ComVisible(true)]
- public interface IDisposable
- {
- // Methods
- void Dispose();
- }
MSDN:
当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存;不过,进行垃圾回收的时间不可预知。另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知。
将此接口的 Dispose 方法与垃圾回收器一起使用来显式释放非托管资源。当不再需要对象时,对象的使用者可以调用此方法。
有两种方式来调用:
第一种方式,使用Using语句会自动调用Dispose方法,代码如下:
第二种方式,现实调用该接口的Dispose方法,代码如下:
- using (BaseResource baseRes= new BaseResource ())
- {
- //方法
- }
两种使用方式效果相同,但具代码可观性来讲建议使用第一种.
- BaseResource baseRes= new BaseResource ();
- try
- {
- //方法
- }
- finally
- {
- IDisposable disposable = baseRes as IDisposable;
- if (disposable != null) disposable.Dispose();
- }
接口的实现方式:
- public class BaseResource : IDisposable
- {
- // 非托管资源
- private IntPtr handle;
- //托管资源
- private Component Components;
- // Dispose是否被调用
- private bool disposed = false;
- public BaseResource()
- {
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- if (!this.disposed)
- {
- if (disposing)
- {
- // 释放托管资源
- Components.Dispose();
- }
- // 释放非托管资源,如果disposing为false,
- // 只有托管资源被释放
- CloseHandle(handle);
- handle = IntPtr.Zero;
- // 注意这里不是线程安全的
- }
- disposed = true;
- }
- // 析构函数只会在我们没有直接调用Dispose方法的时候调用
- // 派生类中不用在次提供析构函数
- ~BaseResource()
- {
- Dispose(false);
- }
- }
上面的模式保证了:
1、 Finalize只释放非托管资源;
2、 Dispose释放托管和非托管资源;
3、 重复调用Finalize和Dispose是没有问题的;
4、 Finalize和Dispose共享相同的资源释放策略,因此他们之间也是没有冲突的。
然而子类继承的时候应该怎么去实现自己的IDisposable呢?方式如下:
- public class MyResourceWrapper : BaseResource
- {
- // 托管资源
- private ManagedResource addedManaged;
- // 非托管资源
- private NativeResource addedNative;
- private bool disposed = false;
- public MyResourceWrapper()
- {
- }
- protected override void Dispose(bool disposing)
- {
- if (!this.disposed)
- {
- try
- {
- if (disposing)
- {
- addedManaged.Dispose();
- }
- CloseHandle(addedNative);
- this.disposed = true;
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
- }
- }