.NET最终确定概念问题

时间:2010-07-05 14:51:15

标签: .net dispose finalize suppress

最好不使用finalize比较处理吗? dispose是否在第一次解析时删除了非托管资源?

什么是压制最终确定?

3 个答案:

答案 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),因此终结器必须存在。尽量不要依赖它。