Frage

In .NET, unter welchen Umständen sollte ich GC.SuppressFinalize() verwenden?

Welchen Vorteil (s) mit dieser Methode geben Sie mir?

War es hilfreich?

Lösung

SuppressFinalize sollte nur von einer Klasse aufgerufen werden, die einen Finalizer hat. Es informiert die Garbage Collector (GC), dass this Objekt wurde vollständig gereinigt.

Die empfohlene IDisposable Muster, wenn Sie haben eine Finalizerthread ist:

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);
    }
}

Normalerweise hält die CLR Tabs auf Objekte mit einem Finalizerthread wenn sie erstellt werden (was sie teurer zu schaffen). SuppressFinalize erzählt die GC, die das Objekt richtig aufgeräumt und muss nicht auf die Finalizerthread Warteschlange gehen. Es sieht aus wie ein C ++ destructor, aber nicht so etwas wie man handeln.

Die SuppressFinalize Optimierung ist nicht trivial, wie Ihre Objekte lange warten auf die Finalizerthread Warteschlange leben können. Nicht versucht, SuppressFinalize rufen andere Objekte, die Sie kümmern. Das ist ein schwerwiegender Mangel warten geschehen.

Konstruktionsrichtlinien informieren uns, dass ein Finalizerthread nicht notwendig ist, wenn Ihr Objekt implementiert IDisposable, aber wenn Sie einen Finalizer haben, sollten Sie IDisposable implementieren deterministische Bereinigung Ihrer Klasse zu ermöglichen.

Die meiste Zeit sollten Sie in der Lage sein, mit IDisposable wegzukommen Ressourcen aufzuräumen. Sie sollten nur einen Finalizer benötigen, wenn Ihr Objekt auf nicht verwalteten Ressourcen hält, und Sie müssen diese Ressourcen zu gewährleisten, werden gereinigt.

Hinweis: Manchmal wird Coder einen Finalizer in dem Debug ihrer eigenen IDisposable Klassen, um diesen Code zu testen baut hat ihr IDisposable Objekt ordnungsgemäß entsorgt werden.

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

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

Andere Tipps

Sie sagen dem System, dass was auch immer Arbeit im Finalizerthread getan worden wäre, ist bereits getan worden, so dass die Finalizerthread nicht aufgerufen werden muss. Aus der .NET-Dokumentation:

  

Objekte, die die IDisposable implementieren   Schnittstelle kann diese Methode aufrufen aus   die Methode IDisposable.Dispose   verhindern, dass die Speicherbereinigungseinrichtung aus   Aufruf Object.Finalize auf einem   Objekt, das sie nicht benötigt wird.

In der Regel sind die meisten jede Methode Dispose () sollte in der Lage sein GC.SupressFinalize () zu nennen, weil es alles aufräumen sollte, die in der Finalizerthread geputzt werden würde.

SupressFinalize ist nur etwas, das eine Optimierung bereitstellt, die das System das Objekt queing zum Finalizerthread nicht stören kann. Ein richtig geschrieben Dispose () / Finalizerthread sollte mit oder ohne Aufruf zu GC.SupressFinalize richtig ().

Das Verfahren muss auf der Dispose-Methode der Objekte aufgerufen werden, die die IDisposable implementiert, auf diese Weise die GC würde die Finalizerthread ein anderes Mal nicht anrufen, wenn someones die Dispose-Methode aufruft.

Siehe auch: http://msdn.microsoft.com /en-us/library/system.gc.suppressfinalize.aspx

 Dispose(true);
 GC.SuppressFinalize(this);

Wenn das Objekt Finalizerthread hat, .net eine Referenz in Finalisierungsschlange setzen

Da wir entsorgen haben rufen (tur), ist es klar, Objekt, so brauchen wir nicht Finalisierungsschlange diesen Job zu machen.

So rufen GC.SuppressFinalize (this) Referenz in Finalisierungsschlange entfernen.

Wenn eine Klasse, oder irgendetwas daraus abgeleitet, könnte die letzte Live-Referenz auf ein Objekt mit einem Finalizerthread halten, dann entweder GC.SuppressFinalize(this) oder GC.KeepAlive(this) sollte nach einer Operation auf dem Objekt aufgerufen werden, die sich negativ könnte von diesem Finalizerthread betroffen sein, so sicherzustellen, dass der Finalizerthread bis nicht ausgeführt wird, nachdem dieser Vorgang abgeschlossen ist.

Die Kosten für GC.KeepAlive() und GC.SuppressFinalize(this) sind im Wesentlichen die gleichen in jeder Klasse, die keine Finalizerthread hat, und Klassen, die Finalizer haben sollte in der Regel GC.SuppressFinalize(this) nennen, so die letztere Funktion als der letzte Schritt des Dispose() nicht immer sein notwendig, aber es wird nicht falsch sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top