.net非托管资源析放学习

  用c#.net时间累计也有一年了,对.net非托管资源析放方式学习总结一下。

在.net中,可以用Using关键字进行析放,被析放的对象必须实现了IDisposable接口。当代码跳出Using关键字包裹的代码域时,系统会调用实例对象的Disposable函数进行析放。IDisposable接口,一个被专门用于析放非托管资源(例如打开的文件句柄,数据库链接等资源)的接口。托管资源由GC负责管理,但是对于非托管资源,GC是不知道该怎么析放的。所以我们要实现IDisposable接口中的Disposbale方法,在方法中手工析放,GC检测到实例对象没有引用时,析放实例对象的托管资源时同时会析放该实例的非托管资源。

那么该怎么设计实现IDisposable接口的实例类呢?虽然C#也有析构函数,但与C++析构函数不同,C#析构函数并不在实例失效时立即调用,实际上无法知道析构函数什么时候调用。而且也不能显示调用析构函数,GC会自动调用析构函数。因为不能保证析构函数很快被执行,所以不能把非托管资源的清理放到析构函数中。

标准实现IDisposable接口代码:

Class MyClass:IDisposable

{

  bool dispose = false;

  public void Dispose()

  {

    Dispose(true);

    GC.SuppressFinalize(this);   //告诉GC,不要只执行析构函数了,因为已经析放了

  }

  ~MyClass()

  {

    Dispose(false);

  }

  protected virtule void Dispose(bool disposing)

  {

    if(dispose == false)

    {

      if(disposing == true)

      {

        //析放托管资源

        .........................

      }

      //析放托管资源

      .........................

    }

    dispose = false;

  }

}

 

如果我们要自己析放,可以调用 Dispose(),否则就由GC去执行析构函数时去调用Dispose(bool disposing).

一般来说,Using关键字适合释放单个非托管资源,因为嵌套的using语句可能存在隐藏的Bug。内层using块引发异常时,将不能释放外层using块的对象资源。

析放多个非托管资源还是用TRY FINNALLY 吧。

 

posted @ 2017-08-20 23:16  青春已逝  阅读(199)  评论(0编辑  收藏  举报