IDisisable和托管资源

时间:2011-11-02 10:48:11

标签: c# garbage-collection idisposable

  

可能重复:
  Proper use of the IDisposable interface

我有一个包含托管和非托管资源的类。我正在使用IDisposable来发布未管理的资源。我应该在dispose方法中释放托管资源吗?或者我可以将它留给GC来发布托管资源?

2 个答案:

答案 0 :(得分:3)

如果您查看以下documentation,您会找到以下行:

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

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

答案 1 :(得分:1)

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

一旦处理完毕,拥有封装在其他对象中的资源的任何类的正确行为通常是在其自己的Dispose方法中调用所有此类资源上的Dispose,而不是实现终结器(和 - -for C# - 没有析构函数,这会导致编译器生成终结器)。如果终结器在一个包含其他可终结对象的对象上运行,那么每个对象通常都处于以下三种状态之一:

  1. 其他对象上的终结器已经运行,在这种情况下,没有必要做任何事情来清理它。
  2. 其他对象的终结器将被安排运行,在这种情况下,可能没有必要做任何事情来清理它。
  3. 其他对象可能存在其他强引用,在这种情况下,它不应该被清除。

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

请注意,顺便说一下,除了释放对象实例直接占用的内存之外,几乎不应该依赖垃圾收集器来做任何事情。确定性处置几乎总是好得多。人们应该刻意使用垃圾收集器来清理资源的唯一时间是创建相对低成本的资源,这些资源在垃圾收集时已经有效地清理自己,并且实例将足够广泛分享说,找出最后一个留下范围的情况否则将是不切实际的。虽然放弃一次性物品有时候有充分的理由,但是没有理由放弃一次性物品总是一个错误(如果放弃一次性物品是合适的,那么证明这样做的理由是合适的。)