您的位置:首页 > Web前端

Effective C# Item18:实现标准Dispose模式

2010-01-14 23:56 274 查看
如果一个类型中包含了非托管的资源,那么我们应该自己编写释放非托管资源的方法。.NET提供了一个标准的用于释放资源的模式,叫做Dispose模式,在这种模式中,类型实现IDisposable接口,并提供一个终结器。这样,正常流程下类型的使用者调用Dispose()方法来释放资源,如果用户忘记调用Dispose()方法, 那么类型的终结器会作为最后的保障来释放对象的非托管资源。

在Dispose模式中,类层次中的根基类应该实现IDisposable接口来释放非托管资源,并且该类型应该添加一个终结器作为保障机制。同时这两个方法最后都要把自己释放资源的方法做成一个虚方法,这样派生类可以重写该虚方法来满足自己的资源管理需要,只有在派生类必须释放自己的资源时,它才需要重写基类中的虚方法,而且必须要调用基类的虚方法。

当垃圾回收器运行时,它会立即释放那些没有终结器的垃圾对象的内存。所有实现了终结器的对象都仍然存储在内存中,但是会添加到一个终结队列中,同时垃圾回收器会创建一个线程来运行这些对象上的终结器,在终结器线程完成它的工作后,这些垃圾对象的内存才有可能被彻底删除。这样需要终结操作的对象会比美元后终结器的对象在内存中停留的时间更长。

当我们实现IDisposable接口时,需要在Dispose()方法中完成以下任务:

释放所有的非托管资源。

释放所有的托管资源。

设置一个状态标记,表明这个对象已经执行过Dispose()方法。

取消对象的终结奥做需求,我们可以通过调用GC.SuppressFinalize(this)来实现。

在一个拥有完整类继承的层次结构中,我们可以按如下方式编写基类释放资源的代码。

代码

public class BadClass
{
// Store a reference to a global object:
private readonly ArrayList _finalizedList;
private string _msg;

public BadClass( ArrayList badList, string msg )
{
// cache the reference:
_finalizedList = badList;
_msg = (string)msg.Clone();
}

~BadClass()
{
// Add this object to the list.
// This object is reachable, no
// longer garbage. It's Back!
_finalizedList.Add( this );
}
}


上述代码在析构函数中,又将对象本身放入到一个列表中,这样对象本身又变为可用的,这样做是不正确的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: