【问题标题】:.NET FINALIZE CONCEPT PROBLEM.NET FINALIZE 概念问题
【发布时间】:2011-03-11 23:02:40
【问题描述】:

不使用 finalize 比较 dispose 真的更好吗?在第一次解析中 dispose 删除非托管资源吗?

什么是抑制 finalize ?

【问题讨论】:

    标签: .net dispose finalize suppress


    【解决方案1】:

    您的 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 的实现和终结器是共享的),因此无需调用终结器,您可以安全地从终结器中删除对象队列(调用 GC.SuppressFinalize(this))。

    【讨论】:

    • 叹息,这是 IDisposable 的常见实现的神话是不可能消除的。
    • 您能否分享有关如何正确实施 IDisposable 的任何链接?
    • 这里的cmets是倒退的。当且仅当 disposing 为真时,您才应该释放托管资源。
    【解决方案2】:

    我写了一篇博文How to Implement IDisposable and Finalizers: 3 Easy Rules,详细描述了何时以及如何使用它们。我也有一些问答on the subject

    关于如何实现IDisposable(以及相应的 FxCop 规则)的臭名昭著的 Microsoft 文档已经过时了。他们确实准确地描述了 Microsoft 如何在 .NET 1.0 中实现 IDisposable...。当 v2.0 发布时,BCL 中的几乎所有类都进行了改造,以遵循与我的博客文章中描述的指南类似的指南(唯一的区别是 Microsoft 确实为类提供了受保护的 Dispose(bool)设计用作基类)。特别是,据我所知,没有 BCL 类同时负责托管和非托管资源。

    【讨论】:

      【解决方案3】:

      通常,Dispose 和 Finalize 都会清理任何非托管资源(例如句柄)。当 GC 检测到不再使用的对象时,会发生以下两种情况之一。最好的情况是,如果对象不需要最终确定(它没有非托管资源或有人称为抑制终结),那么它会立即被清理。最坏的情况是,它会被放到另一个区域来处理需要完成的事情,并且寿命更长(挂在那些非托管资源上的时间更长),直到最终终结器运行并且对象已被完全清理。

      拥有大量需要完成的对象会显着影响性能。 Disposing 有两个目的:它返回非托管资源,并抑制终结器(假设您已正确实现 Dispose),这使 GC 休息。尽管如此,人们可能会忘记调用 Dispose(或使用 Using),因此终结器必须存在。尽量不要依赖它。

      【讨论】:

        猜你喜欢
        • 2011-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-21
        • 2011-07-31
        • 1970-01-01
        相关资源
        最近更新 更多