Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IDisposable GC.SuppressFinalize(此)位置_C#_.net_Idisposable_Suppressfinalize - Fatal编程技术网

C# IDisposable GC.SuppressFinalize(此)位置

C# IDisposable GC.SuppressFinalize(此)位置,c#,.net,idisposable,suppressfinalize,C#,.net,Idisposable,Suppressfinalize,我对代码使用默认的IDisposable实现模板(模式) 片段: public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool isDisposing) { if (!this.disposed) { if (isDisposing) { //cleanup m

我对代码使用默认的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(isDisposing)”部分

像这样:

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

           GC.SuppressFinalize(this);
       }

       //cleanup unmanaged resources

       this.disposed = true;
    }
}

其思想是清理代码只应调用一次。但是,有两个入口点:
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. 

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


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

我想这显然是一种模板设计模式

您的抽象类设计用于处理所有重要/必要的任务(此处为GC.SuppressFinalize(this)),并允许派生类仅重写部分代码

这里有两种情况:
Dispose中的SuppressFinalize片段1 Dispose中的代码段2,SuppressFinalize(true)

这里的代码片段1确保始终执行GC.SuppressFinalize。而代码段2则让GC.SuppressFinalize的执行任由派生类的支配

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


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

原因。Dispose是指托管代码(您的代码)处理对象,从而选择退出最终确定。人们通常通过最终用户创建另一条进入Dispose(bool disposing)的路由,最终用户的调用没有任何意义。

Dispose(bool isDisposing)方法不是接口的一部分

您通常会从方法中调用
Dispose(true)
,并从终结器中调用
Dispose(false)
,作为尚未处理对象的回退

调用告诉GC不需要调用对象的终结器,可能是因为所有清理都是在调用
Dispose
时完成的

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


Joe Duffy有一些很好的方法。

由于Stackoverflow支持标记,您不应该在邮件标题前面加上[.NET];-)类似的问题-但如果我多次呼吁公众处置(因为根据指导原则,这应该是可能的),那么压制呼吁也会多次呼吁。不应该是这样的。。。在我的代码示例中,它只会被调用一次。尽管Dispose可以被调用多次,但它通常是代码库中其他地方出现问题的征兆——两段或多段代码认为它们控制了对象的生命周期。类似地,可以多次调用GC.SuppressFinalize。虽然在多次调用Dispose时,它可能是代码中的一个缺陷,但应该对它进行防御性编程,以便它能够处理它。多次调用SuppressFinalize不是问题。但这是问题的一个迹象。我的示例是一个具有IDisposable的复杂基类结构。我用IDisposable实现(模板)搜索了许多场景,但没有找到正确的基类->派生类示例。这不是一个完整的示例@MSDN:MSDN只显示基类实现,而不是基类/派生类示例。感谢您提供的信息,但这是主题吗?看看我的具体问题,这是关于抑制调用的位置。你问题中的示例没有终结器,如果你的“真实”代码也是这样,那么无论你在哪里调用抑制终结器都是不相关/不必要的,因为没有要抑制的终结器。@Henk,绝对正确,我应该在回答中说清楚。我想指出的一点是,如果您的类首先没有终结器,那么调用SuppressFinalize的位置是完全不相关的@亨克,不一定。终结器很昂贵。只有在绝对需要时才应该实现终结器,除非类直接处理非托管资源,否则不应该实现终结器。在使用非托管资源时,如果没有使用Dispose()调用,则必须使用终结器来清理非托管内容。当派生类忽略基Dispose调用时,则不会清理更多资源…我认为正确实现基调用是派生类的责任,所以我还是喜欢我的解决方案。@PatrickPeters:如果派生类的资源需要在父类的资源之后进行清理,则在该派生类完成清理之前,不应调用
GC.SuppressFinalize
。将
SuppressFinalize
调用放在虚拟方法中会导致其被提前调用。