关于c#:IDisposable和托管资源

IDisposable and managed resources

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Proper use of the IDisposable interface

我有一个既有托管资源又有非托管资源的类。我正在使用IDisposable释放未管理的资源。我应该释放Dispose方法中的托管资源吗?或者我可以把它留给GC来释放托管资源?


如果您查看以下文档,您将找到该行:

  • 释放类型在其Dispose方法中拥有的任何可释放资源。

因此,在Dispose方法中,您应该释放也实现IDisposable的托管资源。如果一个对象没有实现这一点,您就不必处理它。


我建议具有终结器的类(C编译器为任何具有析构函数的类生成终结器)应避免保存对终结中不使用的任何对象的引用。除了相对较少的例外情况,那些保存在对象中封装的资源的类应该避免保存未封装的资源。相反,这些资源应该封装到它们自己的对象中,这样它们就可以与包含对象的其他资源一起保存。

一旦处理好了这一点,对于拥有封装在其他对象中的资源的任何类,其正确行为通常是在其自己的Dispose方法中对所有此类资源调用Dispose,而不是实现终结器(对于C,没有析构函数,这将导致编译器生成终结器)。如果终结器在保存其他可终结对象的对象上运行,则这些对象通常处于以下三种状态之一:

  • 另一个对象上的终结器已经运行,在这种情况下,不需要做任何事情来清理它。
  • 另一个对象上的终结器将按计划运行,在这种情况下,可能不需要做任何事情来清理它。
  • 其他强引用可能存在于该其他对象,在这种情况下,它还不应该被清除。

    只有在第二种情况下,才有理由考虑对另一个对象进行任何清理。

    注意,顺便说一句,除了释放对象实例直接消耗的内存之外,几乎不应该依赖垃圾收集器来做任何事情。确定性处理几乎总是好得多。唯一一次应该故意使用垃圾收集器来清理资源的时候,就是当一个人要创建成本相对较低的资源时,这种资源在垃圾收集时可以有效地清理自己,并且这些实例将被广泛共享,从而发现最后一个实例何时离开作用域,否则将是实用。虽然有时放弃一次性物品有很好的理由,但没有理由放弃一次性物品总是一个错误(如果放弃一次性物品是合适的,那么为自己的理由这样做是合适的)。