当前位置:  开发笔记 > 编程语言 > 正文

我什么时候应该使用GC.SuppressFinalize()?

如何解决《我什么时候应该使用GC.SuppressFinalize()?》经验,为你挑选了2个好方法。

在.NET中,我应该在哪种情况下使用GC.SuppressFinalize()

使用这种方法有什么好处?



1> Robert Pauls..:

SuppressFinalize只能由具有终结器的类调用.它通知垃圾收集器(GC)this完全清理了对象.

有终结器时推荐的IDisposable模式是:

public class MyClass : IDisposable
{
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // called via myClass.Dispose(). 
                // OK to use any private object references
            }
            // Release unmanaged resources.
            // Set large fields to null.                
            disposed = true;
        }
    }

    public void Dispose() // Implement IDisposable
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
}

通常,CLR在创建对象时会使用终结器对对象进行标记(使创建成本更高).SuppressFinalize告诉GC该对象已正确清理,无需进入终结器队列.它看起来像一个C++析构函数,但不会像一个人那样行事.

SuppressFinalize优化并不简单,因为您的对象可以在终结器队列上等待很长时间.不要试图在其他物体上调用SuppressFinalize.这是一个等待发生的严重缺陷.

设计指南告诉我们,如果您的对象实现了IDisposable,则不需要终结器,但如果您有终结器,则应实现IDisposable以允许确定性地清理您的类.

大多数情况下,您应该能够使用IDisposable来清理资源.当对象保留在非托管资源上并且需要保证清理这些资源时,您应该只需要一个终结器.

注意:有时编码器会添加一个终结器来调试自己的IDisposable类的构建,以便测试代码是否正确处理了它们的IDisposable对象.

    public void Dispose() // Implement IDisposable
    {
        Dispose(true);
    #if DEBUG
        GC.SuppressFinalize(this);
    #endif
    }

    #if DEBUG
    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
    #endif


如果实现`IDisposable`的类不是`sealed`,那么它应该包括对`GC.SuppressFinalize(this)`*的调用,即使它不包含用户定义的终结器*.这对于确保添加用户定义的终结器但只覆盖受保护的`Dispose(bool)`方法的派生类型的正确语义是必要的.
@Dreamer - 这取决于你的实现.通常,您想知道终结器是否正在调用Dispose而不是IDisposable.Dispose()实现.如果从终结器调用,您必须假定私有引用不再有效,并且您实际上做不了多少.如果从IDisposable.Dispose()调用,您知道引用仍然有效.

2> Michael Burr..:

你告诉系统,在终结器中完成的任何工作都已经完成,所以不需要调用终结器.从.NET文档:

实现IDisposable接口的对象可以从IDisposable.Dispose方法调用此方法,以防止垃圾收集器在不需要它的对象上调用Object.Finalize.

通常,大多数Dispose()方法都应该能够调用GC.SupressFinalize(),因为它应该清理在终结器中清理的所有内容.

SupressFinalize只是提供一种优化,允许系统不打扰将对象排队到终结器线程.无论是否调用GC.SupressFinalize(),正确编写的Dispose()/终结器都可以正常工作.

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有