释放未托管资源

释放未托管资源

垃圾收集器的出现,使得我们不需要担心不再需要担心的对象,对于已经托管的对象,只要它不再被引用,那么垃圾收集器就能在需

要时释放资源。但是,垃圾收集只不知道如何释放北托管的资源(如文件句柄、网络连接和数据库连接)。

定义类时,可以使用两种机制来自动释放非托管资源:
(1)声明一个析构函数,作为类的成员
(2)在类中实现System.IDisponsable接口


1、析构函数



在垃圾收集器删除对象之前,它会调用析构函数。在.NET的底层结构中,析构函数被称为Finalizers,就终结器度。在C#中定义的析

构函数,编译器发送给程序集的实际上是Finalize()方法,如果你需要查看程序集的内容,就应该知道这个事实。
C#的析构函数的使用十分少,因为它们执行时的不确定性。由于垃圾收集器的工作方式,无法确定C#引用对象的析构函数何时执行,

所以无法在析构函数中放置需要在某一时间运行的代码,也不应该使用能又任意顺序对不同类实例调用的析构函数。
另外的一个问题是,C#析构函数的执行会延迟对象从内存删除的时间。没有析构函数的对象会在垃圾收集器工作时一次完成,而有析

构函数的对象需要两次处理才能删除。另外,运行库使用了一个线程来执行所有对象的Finalize()方法。过于频繁使用析构函数,和

对性能有显著的影响。


2、IDisposable接口



推荐使用System.IDisposable接口替代析构函数。IDisposable接口定义了一个模式,为释放未托管的资源提供了确定机制,并避免

了产生析构函数固有的与垃圾收集器相关的问题。它声明了一个Dispose()方法,不带参数,返回void,如下:
class MyClass : IDisposable
{
    public void Dispose();
    {
         // implementation
    }
}
通过调用Dispose()方法,可以显示释放因对象直接使用的所有未托管资源。
然而,如果代码如下:
    ResourceGobbler theInstance = new ResourceGobbler();
    // do something
    theInstance.Dispose();
这样,在这个过程中可能出现异常,使得释放资源失败,如果采用了try来捕捉异常,又使得代码比较长。那么,我们可以使用using

指令来完成这个工作。
   using(RescourseGobbler theInstance = new RescourceGobbler())
   {
      // do something
   }
那么,在using语句中实例化或者声明的变量,在变量超出作用域的时候,即使出现了异常的,也会自动调用其Dispose()方法。

另外,有时候也使用Close()来代替Dispose()的功能,如处理文件或数据库连接时。这些情况下,常常实现IDisposable接口,然后

执行一个独立的Close()方法,来调用Dispose()。


3、实现IDisposable接口和析构函数



虽然说C#提供了两种未托管资源的释放方式,使用析构函数造成系统的开销大,而使用IDisposable接口就要求用户必须确保执行了

Dispose()。一般情况下,最好的办法的是执行这两种机制,实现优缺点的互补

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值