IDisposable.Dispose 方法是执行与释放或重置非托管资源相关的应用程序定义的任务。
void Dispose();
使用此方法关闭或释放由实现此接口的类的实例保持的文件、流和句柄等非托管资源。根据约定,此方法用于与释放对象保持的资源或准备对象以便重新使用有关的所有任务。
实现此方法时,对象必须通过在包容层次结构中传播调用来进行查找,以确保释放所有保持的资源。例如,如果对象 A 分配对象 B,而对象 B 又分配对象 C,那么 A 的 Dispose 实现必须对 B 调用 Dispose,而 B 反过来对 C 调用 Dispose。如果对象的基类实现了 IDisposable,对象还必须调用它们基类的 Dispose 方法。
如果某对象的 Dispose 方法被调用一次以上,则该对象必须忽略第一次调用后的所有调用。如果对象的 Dispose 方法被调用多次,对象不得引发异常。如果由于资源已被释放且以前未调用 Dispose 而发生错误时,Dispose 会引发异常。
资源类型可能使用特定的约定来表示已分配状态和已释放状态。流类即是这样一种示例,传统上认为它们要么打开要么关闭。具有此类约定的类可能选择实现带有自定义名称(如 Close)的公共方法,由该方法调用 Dispose 方法。
因为 Dispose 方法必须显式进行调用,所以,实现 IDisposable 的对象还必须实现一个完成器,以便在未调用 Dispose 时处理释放资源问题。默认情况下,垃圾回收器会在回收对象的内存之前自动调用对象的完成器。然而,在调用 Dispose 方法后,通常不需要垃圾回收器调用已处置对象的完成器。为防止自动终止,Dispose 实现可以调用 GC.SuppressFinalize 方法。
有关实现完成器的更多信息,请参见 GC 类和 Object.Finalize 方法。
.NET中用于释放对象资源的接口是IDisposable,但是这个接口的实现还是比较有讲究的。尤其是在VS2005新增加了Using(...){...}语句后,就要求在这里初始化的对象必须拥有自身的Dispose能力。也就是说必须继承自IDisposable接口,并实现其Dispose方法。
建议的模式是:
- public class BaseResource: IDisposable
- {
- public void Close()
- {
- Dispose();
- }
- void IDisposable.Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- // 同前
- }
- }
这里使用了一个所谓的接口显式实现:void IDisposable.Dispose()。这个显式实现只能通过接口来访问,但是不能通过实现类来访问。因此:
- BaseResource baseRes= new BaseResource ();
- baseRes.Dispose(); // 错误
- (baseRes as IDisposable).Dispose(); // 正确