C#释放资源(2)

  • Post author:
  • Post category:其他


C#中垃圾收集器的出现意为着,通常不需要担心不再需要的对象,只要让这些对象的所有引用都超出作用域,并允许垃圾收集器在需要时释放资源即可。但是,垃圾收集器不知道如何释放未托管的资源(例如文件句柄、网络链接和数据库链接)。托管类在封装对未托管资源的直接或间接引用时,需要制定专门的规则,确保未托管资源在回收类的一个实例时释放。

在定义一个类时,可以使用两种机制来自动释放未托管资源。这些机制常常放在一起实现,因为每个机制都为问题解决提供了不同的解决方法。这两种机制是:

声明一个析构函数,作为类的一个成员

在类中实现System.IDisposable接口

实现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 (!isDispose)

{


if (disposing)

{


//Cleanup managed objects by calling their Dispose() methods

}

//Cleanup unmanaged objects

}

isDispose = true;

}

~ResourceHolder()

{


Dispose(false);

}

}

可以看出,Dispose()有第二个protected重载方法,它带一个bool参数,这是真正完成清理工作的方法。Dispose(bool)由析构函数和IDisposable.Dispose()调用。这个方法的重点是确保所有的清理代码都放在一个地方。