我什么时候需要管理托管资源?

我一直在看标准的Dispose模式,我只是想知道我需要写什么来免费管理资源? 如果这些资源已经“管理”,那么我肯定不需要做任何事情。

如果是这种情况,并且我的类没有任何非托管资源(因此不需要GC最终确定)那么我只需要在Dispose方法中抑制终结吗? : –

public void Dispose() { GC.SuppressFinalize(this); } 

所以假设这是我的class级:

 public sealed class MyClass : IDisposable { IList objects; // MyObject doesn't hold any unmanaged resource private bool _disposed; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!_disposed) { // do I need to set the list to null and // call Dispose on each item in the list? if (disposing) { foreach (var o in objects) o.Dispose(); objects = null; } } _disposed = true; } ~MyClass() { Dispose(false); } } 

我是否真的需要在这里释放托管资源?

谢谢,

如果您的类包含任何IDisposable实例,那么您正在使用托管资源,因此您应该实现IDisposable以允许用户处置资源。 您的Dispose方法应该在托管资源上调用Dispose

至于释放托管内存,您不需要做任何事情。 这是由GC处理的,但这是GC处理的清理的唯一部分。 必须通过Dispose和/或终结器清理托管和非托管资源。

如果您不使用任何托管或非托管资源,则无需同时实现IDisposable和finalizer。 实现终结器实际上会影响您的类型的性能,因此除非您需要,否则不要实现它。

您应该处置实现IDisposable任何托管对象。

您将无法在未实现IDisposable对象上调用Dispose ,因此您需要检查它。 (显然,如果MyObject所有可能实例/后代都将始终实现IDisposable那么您将不需要该检查。)

没有必要将列表本身设置为null

在一般情况下,我可能会重新编写循环看起来像这样:

 if (disposing) { foreach (var o in objects) { var d = o as IDisposable; if (d != null) d.Dispose(); } } 

(顺便说一句,如果你的类实际上没有持有任何IDisposable对象或非托管资源,那么你可能根本不需要实现IDisposable或者终结者。)

实现IDisposable有两个原因:
1.释放联合国管理的资源。 这个案子非常罕见 – 但不幸的是,这是很多博士谈论的内容。 这是关于什么是免费的 – 即避免泄漏的资源/记忆。
2.释放MANAGED资源。 这很常见 – 它不是关于确保被释放的内容(因为管理资源总是会在某些时候被GC 释放 ),而是关于什么时候被释放 。 即它是关于为用户提供对象控制的,当它释放托管资源时(即当它关闭套接字或文件等)时,其他东西可以得到它们。

在您的情况下,如果没有派生类添加托管资源,您可以使用以下最小配置 :

 public virtual void Dispose() { foreach (var o in objects) { var d = o as IDisposable; if (d != null) d.Dispose(); } }