根据Essential C# 6.0类调用.Dispose(),你应该:上有一个终结
避免在有一个终结所拥有的对象调用Dispose()。 取而代之,依靠最终化队列来清理实例。
- 可能有人请详细说明这是我不是什么处分的一点是,如果我们不能从拥有的对象调用它清楚了吗?
- 除了Reflection,你会如何判断对象是否有
Finalizer
? - 除了搜索API文档(如果您有权访问它并存在)或反射,您如何找出何时调用
Close()
/Close()
+Dispose()
?我在网络上看到很多关于特定类型的问题(MemoryStream
/Form
/SqlConnection
/etc),但我更多地关注“如何自己弄清楚”。
按照Dispose Pattern你应该:
考虑提供方法Close()除Dispose()方法,如果是靠近该地区的标准术语。这样做时,使关闭实现与Dispose相同并考虑显式实现IDisposable.Dispose方法非常重要。
,但有些时候,你应该像Form
同时调用等类似问题“Close and Dispose - which to call?”接近但也有来自
是没有定义的方法除了像往常一样,答案是:这要看情况。不同的类以不同的方式实现IDisposable,并且由您来做必要的研究。
编辑:以下是完整的指南,问我有没有允许复制,但因为它是一个指导方针(从而假定它应该被自由共享的公共知识)和实际培训材料不是某一部分,我希望我没有违反任何规则。
准则
DO只能用于使用稀缺或昂贵的资源对象实现一个终结方法,即使最终确定延迟垃圾回收。
DO实现IDisposable来支持带终结器的类的确定性终结。
如果Dispose()未被明确调用,那么在实现IDisposable的类上实现一个终结器方法。
重构一个终结方法来调用与IDisposable相同的代码,也许只需调用Dispose()方法即可。
不要抛出终结器方法的异常。
从Dispose()调用System.GC.SuppressFinalize()以避免重复资源清理并延迟对象的垃圾回收。
确保Dispose()是幂等的(应该可以多次调用Dispose())。
保持Dispose()简单,侧重于最终确定所需的资源清理。
AVOID在拥有终结器的拥有对象上调用Dispose()。相反,依靠最终化队列来清理实例。
AVOID引用其他在定稿过程中未定稿的对象。
重写Dispose()时,DO调用基类的Dispose()方法。
考虑确保在调用Dispose()后对象变得不可用。处理完一个对象之后,除Dispose()(可能会多次调用它)之外的其他方法应抛出ObjectDisposedException。
DO对拥有一次性字段(或属性)的类型执行IDisposable并处理所述实例。
关于如何做适当的资源处置,我见过最好的非SO文章是“[IDisposable:你的母亲从来没有告诉过你关于资源释放](http://www.codeproject.com/Articles/29534/IDisposable-What - 你的母亲从来没有告诉你关于)“[斯蒂芬Cleary](http://stackoverflow.com/users/263693/stephen-cleary) –
这是一个很好的答案彼得,我已经添加完整指南。在发布准则之后,重新阅读准则和您的评论,从我的角度来看,您认为它看起来像是与终结者有关,而我在与IDisposable有关的印象之下是正确的。Dispose()这就是为什么我很困惑。我也喜欢你对第2点的回答,我可以在SafeHandles上进行一些进一步的研究。关于第3点,似乎纯粹的经验和试验和错误几乎是一天的顺序。我的强迫症很激动。 – Storm
@Storm我在上一篇评论中链接到的文章讨论了SafeHandles如何工作以及如何正确*实现您自己的。 –