C#释放未托管的资源

1 使用System.IDisposable接口替代析构函数。IDisposable接口声明了一个方法Dispose(),他不带参数,

  返回void。假定有一个类ResourceGobbler,它使用某些外部资源,且实现IDisposable接口。如果要实例

  化这个类的实例,使用它,然后释放它,就可以使用下面的代码:

  class ResourceGobbler:IDisposable

  {

      public void Dispose()

      {

          //implementation

      }

  }

  //另一端引用代码

  ResourceGobbler theInstance=null;

  try

  {

      theInstance=new ResourceGobbler();

      //do your processing

      finally

      {

          if(theInstance!=null)theInstance.Dispose();

      }

  }

  如果重视要重复这样的结构,代码就很容易被混淆。C#提供了一种语法,可以确保在对象引用超出作用域

  时,在执行IDisposable接口的对象上自动调用Dispose()。该语法使用了Using关键字来完成这一工作

  下面的代码生成与try块相对应的IL代码:

  using(ResourceGobbler theInstance=new ResourceGobbler())

  {

       //do your processing

  }

  using语句的后面是一对圆括号,其中是引用变量的声明和实例化,该语句使变量放在其后的语句块中。

  另外,在变量超出作用域时,即使出现异常,也会自动调用其Dispose()方法。如果已经使用try块来捕

  获其他异常,就会比较清晰,如果避免使用using,仅在已有的try块finally子句中调用Dispose(),可

  以避免进行额外的缩进。

2 实现IDisposable接口和析构函数

  IDisposable接口提供了一种机制,允许类的用户控制释放资源的时间,但需要确保执行Dispose(),一

  般情况下,最好的方法是与析构函数配合使用,如下例子:

  public class ResourceHolder:IDisposable

  {

      private bool isDispose=false;

      public void Dispose()

      {

           Dispose(true);

           GC.SuppressFinalize(this);

      }

      protected virtual void Dispose(bool disposing)

      {

           if(!isDisposed)

           {

               if(disposing)

               {

                    //cleanup managed objects by calling their Dispose() methods.

               }

               //cleanup unmanaged objects

           }

           isDisposed=true;

      }

      ~ResourceHolder()

       {

            Dispose(false);

       }

 

      public void SomeMethod()

      {

           //Ensure object not already disposed before execution of any method

           if(isDisposed)

           {

                throw new ObjectDisposedException("ResourceHolder");

           }

      }

  }

  可以看出Dispose()有第二个Protected重载方法,他带一个bool参数,这是真正完成清理工作方法。

  Dispose(bool)有析构函数和IDisposable.Dispose()调用。这个方式的重点确保所有的清理代码都放在

  一个地方。

  传递给Dispose(bool)的参数表示Dispose(bool)是由析构函数调用,还是由IDisposable.Dispose()调

  用——Dispose(bool)不应从代码的其他地方调用,其原因是:

  (1)如果客户调用IDisposable.Dispose(),该客户就指定应清理所有与该对象相关的资源,宝库托管和

       非托管资源。

   (2) 如果调用了析构函数,原则上所有的资源仍需要清理,但是在这种情况下,析构函数必须由垃圾

       收集器调用,而且不应访问其他托管的对象,因为我们不再能确定他们的状态了,在这种情况下,

       最好清理已知的未托管资源,希望引用的托管对象还有析构函数,执行自己的清理过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值