C# 对具有终结器的类调用.Dispose()
根据你的意见,你应该: 避免对拥有终结器的对象调用Dispose()。 相反,依赖终结队列来清理实例C# 对具有终结器的类调用.Dispose(),c#,dispose,finalizer,C#,Dispose,Finalizer,根据你的意见,你应该: 避免对拥有终结器的对象调用Dispose()。 相反,依赖终结队列来清理实例 有人能详细说明一下吗?因为我不清楚如果我们不是从拥有的对象中调用Dispose的意义是什么 除了反射之外,您如何确定对象是否具有终结器 除了搜索API文档(如果您可以访问并且它存在)或反射之外,您如何确定何时调用Close()/Close()+Dispose()?我在网上看到了很多关于特定类型的问题(MemoryStream/Form/SqlConnection/等等),但我更多关注的是“如何自
终结器
Close()
/Close()
+Dispose()
?我在网上看到了很多关于特定类型的问题(MemoryStream
/Form
/SqlConnection
/等等),但我更多关注的是“如何自己解决它”表单等方式调用这两种方法。类似于“接近”的问题,但除了
和往常一样,答案是:视情况而定。不同的类以不同的方式实现IDisposable,这取决于您进行必要的研究
编辑:这是完整的指南,我没有申请复制许可,但因为这是一个指南(因此假设它应该是免费分享的公共知识),而不是实际培训材料的一部分,我希望我没有违反任何规则
指南
请仅在资源稀缺或昂贵的对象上实现终结器方法,即使终结会延迟垃圾收集。
实现IDisposable以支持带有终结器的类的确定性终结。
如果未显式调用Dispose(),请在实现IDisposable的类上实现终结器方法。
重构一个finalization方法以调用与IDisposable相同的代码,可能只是调用Dispose()方法。
不要从终结器方法抛出异常。
从Dispose()调用System.GC.SuppressFinalize(),以避免重复资源清理和延迟对象上的垃圾收集。
确保Dispose()是幂等的(应该可以多次调用Dispose()。
务必使Dispose()保持简单,重点是完成所需的资源清理。
避免对拥有终结器的对象调用Dispose()。相反,依赖终结队列来清理实例。
避免引用在最终确定期间未最终确定的其他对象。
重写Dispose()时,一定要调用基类的Dispose()方法。
考虑在调用Debug()之后确保对象变得不可用。对象被释放后,Dispose()以外的方法(可能被多次调用)应抛出ObjectDisposedException。
在拥有一次性字段(或属性)的类型上实现IDisposable,并处理所述实例
有人能详细说明一下吗?因为我不清楚如果我们不是从拥有的对象中调用Dispose的意义是什么
如果没有这本书的全文和它的上下文(我没有这本书的副本,很多其他人也可能没有读过你的问题),就不可能确切地说出它们的意思。但这本书应该是一本好书,因此我必须假设您引用的文本只适用于您自己的终结器中的代码。也就是说,您当然应该正常处置自有物品。在Dispose()
方法中
这是关于如果你的物品没有得到妥善处理该怎么办。答案就是清理你自己的非托管资源
与此相关的是,随着SafeHandle
类的出现(不久前),您可能根本不需要终结器。相反,将您自己的非托管资源包装在SafeHandle
子类中,并让该类处理终结
除了反射,您如何确定对象是否具有终结器
除了反射之外,您还需要依赖源代码(如果可用)、文档(如果编写的话),或者仅仅是对象实现了IDisposable
(即,做出一个假设……这并不能保证,但两者之间有很强的相关性)
更重要的是,请注意,由于可以在不使用终结器的情况下正确实现实现IDisposable
的对象(例如,如果您使用SafeHandle
,或者如果您实现IDisposable
,只是为了能够确定地清理拥有的IDisposable
对象),不能保证终结器的存在
我认为更好的表述指南的方式是“不要在终结器中处理对象”。依赖这样一个事实,即IDisposable
对象本身应该以某种方式完成自己拥有的资源,并且只关注自己对象直接拥有的任何非托管资源
除了搜索API文档(如果您有权访问并且它存在)或反射之外,您如何确定何时调用Close()/Close()+Dispose()?我在网上看到了很多关于特定类型(MemoryStream/Form/SqlConnection/etc)的问题,但我更多关注的是“如何自己解决这个问题”
你不能。除非仔细检查代码。也就是说
您不应该同时调用Close()
和Dispose()
。两者应该永远是等价的,