Auf Englisch lesen

Freigeben über


IDisposable.Dispose Methode

Definition

Führt anwendungsspezifische Aufgaben durch, die mit der Freigabe, der Zurückgabe oder dem Zurücksetzen von nicht verwalteten Ressourcen zusammenhängen.

C#
public void Dispose();

Beispiele

Das folgende Beispiel zeigt, wie Sie die Dispose -Methode implementieren können.

C#
using System;
using System.ComponentModel;

// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.

public class DisposeExample
{
    // A base class that implements IDisposable.
    // By implementing IDisposable, you are announcing that
    // instances of this type allocate scarce resources.
    public class MyResource: IDisposable
    {
        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;

        // The class constructor.
        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        // Implement IDisposable.
        // Do not make this method virtual.
        // A derived class should not be able to override this method.
        public void Dispose()
        {
            Dispose(disposing: true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SuppressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the
        // runtime from inside the finalizer and you should not reference
        // other objects. Only unmanaged resources can be disposed.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if(!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up
                // unmanaged resources here.
                // If disposing is false,
                // only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;
            }
        }

        // Use interop to call the method necessary
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# finalizer syntax for finalization code.
        // This finalizer will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide finalizer in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(disposing: false) is optimal in terms of
            // readability and maintainability.
            Dispose(disposing: false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.
    }
}

Hinweise

Verwenden Sie diese Methode, um nicht verwaltete Ressourcen wie Dateien, Streams und Handles, die von einer Instanz der -Klasse gespeichert werden, die diese Schnittstelle implementiert, zu schließen oder freizugeben. Gemäß Konvention wird diese Methode für alle Aufgaben verwendet, die dem Freigeben von Ressourcen, die von einem Objekt gehalten werden, oder der Vorbereitung eines Objekts für die Wiederverwendung zugeordnet sind.

Warnung

Wenn Sie eine Klasse verwenden, die die IDisposable -Schnittstelle implementiert, sollten Sie deren Dispose Implementierung aufrufen, wenn Sie mit der Verwendung der -Klasse fertig sind. Weitere Informationen finden Sie im Abschnitt "Verwenden eines Objekts, das IDisposable implementiert" im IDisposable Thema.

Stellen Sie bei der Implementierung dieser Methode sicher, dass alle gehaltenen Ressourcen freigegeben werden, indem Sie den Aufruf über die Einschlusshierarchie weitergeben. Wenn beispielsweise ein Objekt A ein Objekt B zuordnet und Objekt B ein Objekt C zuordnet, muss die Implementierung von Dispose A auf B aufrufen Dispose , wodurch wiederum C aufgerufen Dispose werden muss.

Wichtig

Der C++-Compiler unterstützt die deterministische Entsorgung von Ressourcen und lässt keine direkte Implementierung der Dispose -Methode zu.

Ein -Objekt muss auch die Dispose -Methode seiner Basisklasse aufrufen, wenn die Basisklasse implementiert IDisposable. Weitere Informationen zum Implementieren IDisposable einer Basisklasse und ihrer Unterklassen finden Sie im Abschnitt "IDisposable und die Vererbungshierarchie" des Themas IDisposable .

Wenn die Dispose Methode eines Objekts mehrmals aufgerufen wird, muss das Objekt alle Aufrufe nach dem ersten ignorieren. Das -Objekt darf keine Ausnahme auslösen, wenn seine Dispose Methode mehrmals aufgerufen wird. Andere Instanzmethoden als Dispose können eine ObjectDisposedException auslösen, wenn Ressourcen bereits verworfen sind.

Benutzer erwarten möglicherweise, dass ein Ressourcentyp eine bestimmte Konvention verwendet, um einen zugeordneten Zustand im Vergleich zu einem freizugebenden Zustand anzugeben. Ein Beispiel hierfür sind Streamklassen, die traditionell als offen oder geschlossen betrachtet werden. Der Implementierer einer Klasse, die über eine solche Konvention verfügt, kann sich dafür entscheiden, eine öffentliche Methode mit einem angepassten Namen zu implementieren, z Close. B. , der die Dispose -Methode aufruft.

Da die Dispose Methode explizit aufgerufen werden muss, besteht immer die Gefahr, dass die nicht verwalteten Ressourcen nicht freigegeben werden, da der Consumer eines Objekts die -Methode nicht aufruft Dispose . Dies kann auf zwei Arten vermieden werden:

  • Umschließen Sie die verwaltete Ressource in ein von System.Runtime.InteropServices.SafeHandleabgeleitetes Objekt. Ihre Dispose Implementierung ruft dann die Dispose -Methode der System.Runtime.InteropServices.SafeHandle -Instanzen auf. Weitere Informationen finden Sie im Abschnitt "Die SafeHandle-Alternative" des Themas Object.Finalize .

  • Implementieren Sie einen Finalizer, um Ressourcen freizugeben, wenn Dispose nicht aufgerufen wird. Standardmäßig ruft der Garbage Collector automatisch den Finalizer eines Objekts auf, bevor er seinen Arbeitsspeicher zurückgibt. Wenn die Dispose -Methode jedoch aufgerufen wurde, ist es in der Regel nicht erforderlich, dass der Garbage Collector den Finalizer des verworfenen Objekts aufruft. Um die automatische Finalisierung zu verhindern, Dispose können Implementierungen die GC.SuppressFinalize -Methode aufrufen.

Wenn Sie ein -Objekt verwenden, das auf nicht verwaltete Ressourcen zugreift, z. B. , StreamWriterempfiehlt es sich, die -Instanz mit einer using -Anweisung zu erstellen. Die using -Anweisung schließt den Stream automatisch und ruft Dispose das -Objekt auf, wenn der Code, der es verwendet, abgeschlossen ist. Ein Beispiel finden Sie in der StreamWriter -Klasse.

Gilt für:

Produkt Versionen
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Weitere Informationen