也谈IDisposable接口(一)

IDisposable接口在.net里算是比较简单的接口,也是讨论的比较多的接口之一.下文总结了些自己的个人看法(如有不对之处,敬请拍砖)并引用了部分MSDN和其他博客的文字(如有侵权,请联系我,如若转载,请注明出处,谢谢。)

首先来看MSDN中关于这个接口的说明:

 
 
  1. [ComVisible(true)]
  2. public interface IDisposable
  3. {
  4.     // Methods
  5.     void Dispose();
  6. }
[ComVisible(true)]:指示该托管类型对 COM 是可见的.

MSDN:

当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存;不过,进行垃圾回收的时间不可预知。另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知。

将此接口的 Dispose 方法与垃圾回收器一起使用来显式释放非托管资源。当不再需要对象时,对象的使用者可以调用此方法。

 

有两种方式来调用:
第一种方式,使用Using语句会自动调用Dispose方法,代码如下: 

 
 
  1. using (BaseResource baseRes= new BaseResource ())
  2.   {
  3.       //方法
  4.   }
第二种方式,现实调用该接口的Dispose方法,代码如下:
 
 
  1. BaseResource baseRes= new BaseResource ();
  2.    try
  3.     {
  4.        //方法
  5.     }
  6.    finally
  7.     {
  8.        IDisposable disposable = baseRes as IDisposable;
  9.        if (disposable != null) disposable.Dispose();
  10.     }
两种使用方式效果相同,但具代码可观性来讲建议使用第一种.
接口的实现方式:
 
 
  1. public class BaseResource : IDisposable
  2.     {
  3.         // 非托管资源
  4.         private IntPtr handle;
  5.         //托管资源
  6.         private Component Components;
  7.         // Dispose是否被调用
  8.         private bool disposed = false;
  9.         public BaseResource()
  10.         {            
  11.         }
  12.        
  13.         public void Dispose()
  14.         {
  15.             Dispose(true);            
  16.             GC.SuppressFinalize(this);
  17.         }
  18.         protected virtual void Dispose(bool disposing)
  19.         {
  20.            
  21.             if (!this.disposed)          
  22.             {               
  23.                 if (disposing)
  24.                 {
  25.                     // 释放托管资源
  26.                     Components.Dispose();
  27.                 }
  28.                 // 释放非托管资源,如果disposing为false, 
  29.                 // 只有托管资源被释放
  30.                 CloseHandle(handle);
  31.                 handle = IntPtr.Zero;
  32.                 // 注意这里不是线程安全的
  33.             }
  34.             disposed = true;
  35.         }
  36.         // 析构函数只会在我们没有直接调用Dispose方法的时候调用
  37.         // 派生类中不用在次提供析构函数
  38.         ~BaseResource()
  39.         {
  40.             Dispose(false);
  41.         }
  42.     }
上面的模式保证了:
   
   
   
   

 

1、 Finalize只释放非托管资源;

2、 Dispose释放托管和非托管资源;

3、 重复调用FinalizeDispose是没有问题的;

4、 FinalizeDispose共享相同的资源释放策略,因此他们之间也是没有冲突的。

 

然而子类继承的时候应该怎么去实现自己的IDisposable呢?方式如下:

  1.  public class MyResourceWrapper : BaseResource
  2.     {
  3.         // 托管资源
  4.         private ManagedResource addedManaged;
  5.         // 非托管资源
  6.         private NativeResource addedNative;
  7.         private bool disposed = false;
  8.        
  9.         public MyResourceWrapper()
  10.         {           
  11.         }
  12.         protected override void Dispose(bool disposing)
  13.         {
  14.             if (!this.disposed)
  15.             {
  16.                 try
  17.                 {
  18.                     if (disposing)
  19.                     {                        
  20.                         addedManaged.Dispose();
  21.                     }
  22.                     
  23.                     CloseHandle(addedNative);
  24.                     this.disposed = true;
  25.                 }
  26.                 finally
  27.                 {                   
  28.                     base.Dispose(disposing);
  29.                 }
  30.             }
  31.         }
  32.     }
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值