最好不使用finalize比较处理吗? dispose是否在第一次解析时删除了非托管资源?
什么是压制最终确定?
答案 0 :(得分:4)
您对IDisposable的实施应该是:
public MyClass : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected Dispose(bool disposing)
{
if( disposing )
{
// release unmanaged resource
}
// release managed resources
}
~MyClass()
{
Dispose(false);
}
}
如果一个对象有一个终结器,CLR会在终结队列中保留对它的引用。如果你手动处理对象(调用Dispose())你已经删除了非托管资源(因为dispose的实现和终结器是共享的),所以不需要调用终结器,你可以安全地从最终化中删除对象queue(调用GC.SuppressFinalize(this))。
答案 1 :(得分:1)
我写了一篇博客文章How to Implement IDisposable and Finalizers: 3 Easy Rules,其中详细描述了何时以及如何使用每篇文章。我还有一些Q& As on the subject。
臭名昭着的Microsoft文档如何实现IDisposable
(以及相应的FxCop规则)已经过时了。他们确实准确地描述了Microsoft如何在.NET 1.0中实现IDisposable
...。当v2.0发布时,几乎所有BCL中的类都被改进为遵循类似于我博客文章中描述的指导原则(唯一的区别是Microsoft 具有受保护的Dispose(bool)
用于设计用作基类的类)。特别是,据我所知,没有BCL类负责托管和非托管资源。
答案 2 :(得分:0)
通常,Dispose和Finalize都会清理所有非托管资源(例如句柄)。当GC检测到某个对象不再使用时,会发生以下两种情况之一。最好的情况是,如果对象不需要最终确定(它没有非托管资源或者名为suppress finalize的人)那么它就会被清理掉。最糟糕的情况是,它被放入另一个需要最终确定的区域,并且寿命更长(更长时间依赖于那些非托管资源),直到最终终结器运行并且对象已经完全清理。
拥有大量需要最终确定的对象会显着影响性能。处置有两个目的:它返回非托管资源,并且它会抑制终结器(假设您已正确实现Dispose),这会使GC中断。但是,人们可能忘记调用Dispose(或使用Using),因此终结器必须存在。尽量不要依赖它。