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

When should I use GC.SuppressFinalize()?(我什么时候应该使用 GC.SuppressFinalize()?)
本文介绍了我什么时候应该使用 GC.SuppressFinalize()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在.NET中,什么情况下应该使用GC.SuppressFinalize()?

In .NET, under which circumstances should I use GC.SuppressFinalize()?

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

What advantage(s) does using this method give me?

推荐答案

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

SuppressFinalize should only be called by a class that has a finalizer. It's informing the Garbage Collector (GC) that this object was cleaned up fully.

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

The recommended IDisposable pattern when you have a finalizer is:

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++ 析构函数,但它的行为却一点也不像.

Normally, the CLR keeps tabs on objects with a finalizer when they are created (making them more expensive to create). SuppressFinalize tells the GC that the object was cleaned up properly and doesn't need to go onto the finalizer queue. It looks like a C++ destructor, but doesn't act anything like one.

SuppressFinalize 优化并非微不足道,因为您的对象可以在终结器队列中等待很长时间.不要试图在其他对象上调用 SuppressFinalize 请注意.这是一个等待发生的严重缺陷.

The SuppressFinalize optimization is not trivial, as your objects can live a long time waiting on the finalizer queue. Don't be tempted to call SuppressFinalize on other objects mind you. That's a serious defect waiting to happen.

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

Design guidelines inform us that a finalizer isn't necessary if your object implements IDisposable, but if you have a finalizer you should implement IDisposable to allow deterministic cleanup of your class.

大多数时候,您应该能够使用 IDisposable 来清理资源.当你的对象持有非托管资源并且你需要保证这些资源被清理时,你应该只需要一个终结器.

Most of the time you should be able to get away with IDisposable to clean up resources. You should only need a finalizer when your object holds onto unmanaged resources and you need to guarantee those resources are cleaned up.

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

Note: Sometimes coders will add a finalizer to debug builds of their own IDisposable classes in order to test that code has disposed their IDisposable object properly.

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

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

这篇关于我什么时候应该使用 GC.SuppressFinalize()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)