IDisposable GC.SuppressFinalize(this) 位置

发布于 2024-07-14 14:17:17 字数 853 浏览 7 评论 0原文

我的代码使用默认的 IDisposable 实现模板(模式)。

片段:

public void Dispose()
{
    Dispose(true);

    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool isDisposing)
{
    if (!this.disposed)
    {
        if (isDisposing)
        {
            //cleanup managed resources
        }

        //cleanup unmanaged resources

        this.disposed = true;
    }
}

我的问题:为什么在 Dispose 公共方法中调用“GC.SuppressFinalize(this)”? 在处置托管资源之后,我会将“GC.SuppressFinalize(this)”放置在受保护方法的“if (isDisusing)”部分中。

像这样:

protected virtual void Dispose(bool isDisposing)
{
    if (!this.disposed)
    {
       if (isDisposing)
       {
           //cleanup managed resources

           GC.SuppressFinalize(this);
       }

       //cleanup unmanaged resources

       this.disposed = true;
    }
}

I use a default IDisposable implementation template (pattern) for my code.

snippet:

public void Dispose()
{
    Dispose(true);

    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool isDisposing)
{
    if (!this.disposed)
    {
        if (isDisposing)
        {
            //cleanup managed resources
        }

        //cleanup unmanaged resources

        this.disposed = true;
    }
}

My question: why is the call "GC.SuppressFinalize(this)" in the Dispose public method? I would place "GC.SuppressFinalize(this)" in the "if (isDisposing)" section of the protected method, after disposing managed resources.

Like this:

protected virtual void Dispose(bool isDisposing)
{
    if (!this.disposed)
    {
       if (isDisposing)
       {
           //cleanup managed resources

           GC.SuppressFinalize(this);
       }

       //cleanup unmanaged resources

       this.disposed = true;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

盛夏已如深秋| 2024-07-21 14:17:17

我认为这是模板设计模式的一个明显案例。

您的抽象类旨在处理所需的所有重要/必要任务(此处为 GC.SuppressFinalize(this)),并允许派生类仅覆盖代码的某些部分。

这里有2个案例:
片段 1,SuppressFinalize,位于 Dispose
代码段 2,SuppressFinalize,在 Dispose(true) 中

这里,代码段 1 确保始终执行 GC.SuppressFinalize。 而代码片段 2 则将 GC.SuppressFinalize 的执行留给了派生类

因此,通过将 GC.SuppressFinalize 放在 Dispose 方法中,作为类的设计者,您将始终确保无论派生类编写什么代码,GC.SuppressFinalize 都将被执行。

这只是在Dispose中编写SuppressFinalize而不是Dispose(true)的好处。

I suppose its a clear case of Template Design pattern.

Your abstract class is Designed to take care of all important/necessary tasks required (Here, GC.SuppressFinalize(this)), and allowing a derived class to override only some part of the code.

There are 2 cases here:
Snippet 1, SuppressFinalize, in Dispose
Snippet 2, SuppressFinalize, in Dispose(true)

Here, Snippet 1, makes sure that GC.SuppressFinalize is always executed. While snippet 2, leaves the execution of GC.SuppressFinalize at the mercy of derived class.

So, by putting GC.SuppressFinalize, in Dispose method, you as a designer of your class will always make sure that irrespective of whatever code written by derived classes, GC.SuppressFinalize will be executed.

This is only the benefit of writing SuppressFinalize in Dispose rather then Dispose(true).

两相知 2024-07-21 14:17:17

Dispose(bool isDisusing) 方法不是 IDisposable 接口。

您通常会从 Dispose 方法,并从终结器中调用 Dispose(false),作为对象尚未被处置的情况下的后备方案。

调用 SuppressFinalize 告诉GC 认为不需要调用对象的终结器,大概是因为所有清理工作都是在调用 Dispose 时完成的。

如果您的类上没有终结器,那么您根本不需要调用 SuppressFinalize,因为没有要抑制的终结器!

Joe Duffy 有一些很棒的有关处置、最终确定、垃圾收集等的指南

The Dispose(bool isDisposing) method isn't part of the IDisposable interface.

You would normally call Dispose(true) from your Dispose method, and call Dispose(false) from your finalizer, as a fallback in the case where the object hasn't already been disposed.

Calling SuppressFinalize tells the GC that there's no need to call your object's finalizer, presumably because all your cleanup was done when Dispose was called.

If you don't have a finalizer on your class, then you don't need to call SuppressFinalize at all, since there's no finalizer to suppress!

Joe Duffy has some great guidelines on disposal, finalization, garbage collection etc.

素衣风尘叹 2024-07-21 14:17:17

我认为可以选择任何一种布局,但可能他们想在受保护的 Dispose 方法中强调“将所有释放代码放入此方法中”,因此他们将其他处置(抑制终结)的工件放在其他地方。

另外,假设派生类有另一个原因调用受保护的 Dispose 方法,但仍然希望发生终结(出于任何想象的原因,我不知道)。

I think either layout could have been chosen, but probably they wanted to emphasize "put all deallocation code in this method" in the protected Dispose method, so they put the other artifact of disposing (Suppressing finalization) elsewhere.

Also, suppose a derived class had another reason for calling the protected Dispose method, but did still want finalization to occur (for whatever imagined reason, I don't know).

蓝礼 2024-07-21 14:17:17

原因 .Dispose 是指托管代码(您的代码)处置对象,从而选择退出终结。 人们通常通过终结器创建另一条进入 Dispose(bool dissetting) 的路径,并且该调用对于终结器来说没有任何意义。

Cause .Dispose is when managed code (your code) disposes of the object thereby opting out of finalisation. People usually create another route into Dispose(bool disposing) via a finaliser and the call wouldn't make any sense for the finaliser to make.

╭ゆ眷念 2024-07-21 14:17:17

这个想法是你的清理代码应该只被调用一次。 但是有两个入口点:Dispose 方法和对象终结器。 当调用 Dispose 时,您可以选择退出终结,以便您的清理代码仅被调用一次。 此处的代码可能会更好地说明这一点。

引用:

// NOTE: Leave out the finalizer altogether if this class doesn't 
// own unmanaged resources itself, but leave the other methods
// exactly as they are. 

The idea is that your cleanup code should only be called once. However there are two points of entry: the Dispose method and object finalizers. When Dispose is called, you opt-out of finalization so that your cleanup code is only called once. The code here might illustrate it better.

Quote:

// NOTE: Leave out the finalizer altogether if this class doesn't 
// own unmanaged resources itself, but leave the other methods
// exactly as they are. 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文