Sto*_*orm 5 c# dispose finalizer
根据Essential C#6.0,你应该:
AVOID在拥有终结器的拥有对象上调用Dispose().相反,依靠终结队列来清理实例.
Finalizer?Close()/ Close()+ Dispose()?对于非常具体的类型(MemoryStream/ Form/ SqlConnection/ etc),我在网络上看到了很多问题,但我更关注"如何自己解决".根据Dispose Pattern你应该:
除了Dispose()之外,CONSIDER提供方法Close(),如果close是该区域中的标准术语.这样做时,将Close实现与Dispose相同并考虑显式实现IDisposable.Dispose方法非常重要.
但有时候你应该像两个人一样打电话Form等.像" 关闭和处理 - 要打电话的人? "这样的问题越来越接近,但除此之外没有明确的方法
像往常一样答案是:这取决于.不同的类以不同的方式实现IDisposable,由您来做必要的研究.
编辑:这是完整的指南,我没有要求复制许可,但因为它是一个指南(因此假设它应该是自由共享的公共知识)而不是实际培训材料的某些部分,我希望我'我没有违反任何规则.
准则
DO仅对具有稀缺或昂贵资源的对象实施终结器方法,即使最终化延迟了垃圾收集.
实现IDisposable以支持具有终结器的类的确定性终结.
如果没有显式调用Dispose(),请对实现IDisposable的类实现终结器方法.
DO重构一个finalization方法来调用与IDisposable相同的代码,也许只是调用Dispose()方法.
不要从终结器方法中抛出异常.
从Dispose()调用System.GC.SuppressFinalize()以避免重复资源清理并延迟对象上的垃圾回收.
确保Dispose()是幂等的(应该可以多次调用Dispose()).
保持Dispose()简单,专注于最终化所需的资源清理.
AVOID在拥有终结器的拥有对象上调用Dispose().相反,依靠终结队列来清理实例.
避免引用在最终确定期间未完成的其他对象.
在重写Dispose()时,请调用基类的Dispose()方法.
在调用Dispose()之后,考虑确保对象变得不可用.在处理了一个对象之后,Dispose()以外的方法(可能被多次调用)应抛出一个ObjectDisposedException.
在具有一次性字段(或属性)的类型上实现IDisposable并处理所述实例.
- 有人可以详细说明这一点,因为我不清楚Dispose的重点是什么,如果我们不从拥有的对象中调用它?
如果没有书的全文及其背景(我没有书的副本,也没有其他人阅读你的问题),就不可能肯定地说出他们的意思.但它应该是一本好书,因此我必须假设你引用的文本仅适用于你自己的终结器中的代码.即你应该正常处理拥有的物品.在你的Dispose()方法.
这是关于如果你的对象没有妥善处理该怎么办.答案就是清理自己的非托管资源.
与此相关的是,现在,随着SafeHandle课程的出现(不久前),您可能根本不需要终结器.相反,将您自己的非托管资源包装在SafeHandle子类中,让该类处理完成.
- 除了Reflection之外,你怎么知道对象是否有Finalizer?
除了反思之外,你将依赖源代码(如果有的话),文档(如果写的话),或者仅仅是对象实现的事实IDisposable(即做出假设......它不能保证,但是它之间有很强的相关性.二).
更重要的是,请注意,因为可以正确实现一个IDisposable不使用终结器而实现的对象(例如,如果您使用SafeHandle,或者IDisposable只是为了确定性地清理拥有的IDisposable对象而实现),则终结器的存在是不保证.
我认为更好的方式来指导指导将是"不要在你的终结器中处理对象".依赖于一个IDisposable对象本身应该以某种方式处理最终自己拥有的资源这一事实,并且只关注你自己的对象直接拥有的任何非托管资源.
- 你怎么知道什么时候调用Close()/ Close()+ Dispose()而不是搜索API文档(如果你有权访问它并且它存在)或者反射?对于非常特定的类型(MemoryStream/Form/SqlConnection/etc),我在网络上看到很多问题,但我更关注"如何自己解决".
你不能.并非仔细检查代码.那说......
你永远不应该同时调用Close()和Dispose().如果正确实现了类,则两者应始终等效.
当然,.NET中没有任何内容可以强制执行.因此,不可能肯定地说你不需要.但是如果你正在处理一种既需要两者的类型,那么它写得很差,也可能在其他方面被打破.最好完全避免完全使用该类型.:)
当然,正如你所指出的,Form类在某些情况下需要调用这两个Close()和Dispose()(在大多数情况下,调用Close()实际上是足够的......这只是因为怪异的方式,他们实行的是你得到的例外模式对话框) .但这是一个非常古老的API,在IDisposable完全理解模式复杂性的全部含义之前设计.人们希望,如果他们不得不再次这样做,微软将不会以同样的方式设计该API(事实上,WPF没有相同的二分法).
现代实现应该更好地更好地遵循良好的约定.
附录:
我做了一点浏览.当然,IDisposableStack Overflow上有很多关于GC,终结,终结器等的文章,但我没有看到任何与你的问题直接相同的文章.这个似乎最接近:
其他可能有用的额外阅读:
什么时候处理方法不被调用?
为什么要调用Dispose()?内存泄漏不会发生?
IDisisable和托管资源
当然,经典:
正确使用IDisposable界面
| 归档时间: |
|
| 查看次数: |
420 次 |
| 最近记录: |