Frage

Ich verwende eine Standard IDisposable Implementierung Vorlage (Muster) für meinen 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;
    }
}

Meine Frage: Warum ist der Ruf „GC.SuppressFinalize (this)“ in der Entsorgung öffentliche Methode? Ich würde platzieren "GC.SuppressFinalize (this)" in dem "if (isDisposing)" des geschützten Verfahren, nach verwalteten Ressourcen zu entsorgen.

Wie folgt aus:

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

           GC.SuppressFinalize(this);
       }

       //cleanup unmanaged resources

       this.disposed = true;
    }
}
War es hilfreich?

Lösung

Ich nehme an, einen klaren Fall von Template Design-Muster.

Ihre abstrakte Klasse ist so konzipiert, alle wichtigen / notwendigen Aufgaben kümmern erforderlich (hier GC.SuppressFinalize (this)) und ermöglicht eine abgeleitete Klasse nur einen Teil des Codes außer Kraft zu setzen.

Es gibt zwei Fälle hier:
Snippet 1, SuppressFinalize, in Entsorgen
Snippet 2, SuppressFinalize, in Dispose (true)

Hier Snippet 1, stellt sicher, dass GC.SuppressFinalize wird immer ausgeführt. Während Schnipsel 2 läßt die Ausführung von GC.SuppressFinalize auf Gedeih und Verderb von abgeleiteten Klasse .

Also, durch GC.SuppressFinalize setzen, in Dispose-Methode, Sie als Designer Ihrer Klasse werden immer darauf achten, dass unabhängig davon, was auch immer Code von abgeleiteten Klassen geschrieben wird GC.SuppressFinalize ausgeführt werden.

Dies ist nur der Nutzen von SuppressFinalize in Entsorgen Schreiben eher dann (true) entsorgen.

Andere Tipps

Das Dispose(bool isDisposing) Verfahren ist nicht Teil der IDisposable Schnittstelle.

Normalerweise würden Sie rufen Dispose(true) von Ihrem Dispose Verfahren und Anruf Dispose(false) von Ihrem Finalizerthread, als Ausweich in dem Fall, in dem das Objekt angeordnet nicht bereits war.

Beim SuppressFinalize Tells der GC, dass kein es gibt benötigen Objekts Finalizerthread zu nennen, vermutlich, weil alle Ihre Bereinigung durchgeführt wurde, als Dispose genannt wurde.

Wenn Sie nicht über einen Finalizer auf Ihrer Klasse haben, dann müssen Sie nicht SuppressFinalize überhaupt nennen, da es keine Finalizerthread ist, zu unterdrücken!

Joe Duffy hat einige große Richtlinien zur Verfügung, Finalisierung, Müllabfuhr usw. .

Ich denke, entweder das Layout gewählt worden sein könnte, aber wahrscheinlich wollte sie „setzt alle Deallokation Code in dieser Methode“ in der geschützten Dispose-Methode betonen, so setzten sie den anderen Artefakt der Entsorgung (Unterdrück Finalisierung) an anderer Stelle.

Auch an, dass eine abgeleitete Klasse einen weiteren Grund für den Aufruf der geschützten Methode Dispose hatte, wollte aber nach wie vor auftreten Abschluss (aus irgendeinem Grund denken, ich weiß nicht).

Ursache .Dispose ist, wenn verwalteten Code (Code) verfügt über das Objekt dadurch aus Finalisierung entscheiden. Die Menschen schaffen in der Regel einen anderen Weg in die Dispose (bool disposing) über einen finaliser und der Anruf würde keinen Sinn machen für die finaliser zu machen.

Die Idee ist, dass Ihr Bereinigungscode sollte nur einmal aufgerufen werden. Allerdings gibt es zwei Eintrittspunkte: die Dispose Methode und Objekt Finalizers. Wenn Dispose genannt wird, Opt-out Sie Finalisierung so dass der Code Bereinigung nur einmal aufgerufen wird. Der Code hier könnte es besser veranschaulichen.

Zitat:

// NOTE: Leave out the finalizer altogether if this class doesn't 
// own unmanaged resources itself, but leave the other methods
// exactly as they are. 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top