IDisposable.Dispose Metoda

Definicja

Wykonuje zdefiniowane przez aplikację zadania skojarzone ze zwalnianiem lub resetowaniem zasobów niezarządzanych.

C#
public void Dispose ();

Przykłady

W poniższym przykładzie pokazano, jak można zaimplementować metodę Dispose .

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.
    }
}

Uwagi

Użyj tej metody, aby zamknąć lub zwolnić niezarządzane zasoby, takie jak pliki, strumienie i uchwyty przechowywane przez wystąpienie klasy, która implementuje ten interfejs. Zgodnie z konwencją ta metoda jest używana dla wszystkich zadań skojarzonych z zwalnianiem zasobów przechowywanych przez obiekt lub przygotowywaniem obiektu do ponownego użycia.

Ostrzeżenie

Jeśli używasz klasy, która implementuje interfejs, po zakończeniu IDisposable korzystania z klasy należy wywołać jego Dispose implementację. Aby uzyskać więcej informacji, zobacz sekcję "Using an object that implements IDisposable" (Używanie obiektu implementujące interfejs IDisposable) w temacie IDisposable .

Podczas implementowania tej metody upewnij się, że wszystkie przechowywane zasoby są zwalniane przez propagowanie wywołania za pośrednictwem hierarchii zawierania. Jeśli na przykład obiekt A przydziela obiekt B, a obiekt B przydziela obiekt C, implementacja Dispose A musi wywołać Dispose metodę B, która musi z kolei wywołać metodę Dispose C.

Ważne

Kompilator języka C++ obsługuje deterministyczną usuwanie zasobów i nie zezwala na bezpośrednią implementację Dispose metody.

Obiekt musi również wywołać metodę Dispose klasy bazowej, jeśli klasa bazowa implementuje IDisposableelement . Aby uzyskać więcej informacji na temat implementowania IDisposable w klasie podstawowej i jej podklasach, zobacz sekcję "IDisposable and the inheritance hierarchy" w temacie IDisposable .

Jeśli metoda obiektu jest wywoływana Dispose więcej niż raz, obiekt musi zignorować wszystkie wywołania po pierwszym. Obiekt nie może zgłaszać wyjątku, jeśli jego Dispose metoda jest wywoływana wiele razy. Metody wystąpienia inne niż Dispose mogą zgłaszać ObjectDisposedException , gdy zasoby są już usuwane.

Użytkownicy mogą oczekiwać, że typ zasobu będzie używał określonej konwencji, aby oznaczyć przydzielony stan w porównaniu z wolnym stanem. Przykładem są klasy strumieni, które są tradycyjnie uważane za otwarte lub zamknięte. Implementator klasy, która ma taką konwencję, może zdecydować się na zaimplementowanie metody publicznej z niestandardową nazwą, taką jak Close, która wywołuje metodę Dispose .

Dispose Ponieważ metoda musi być wywoływana jawnie, zawsze istnieje niebezpieczeństwo, że niezarządzane zasoby nie zostaną zwolnione, ponieważ użytkownik obiektu nie wywoła metody Dispose . Istnieją dwa sposoby, aby tego uniknąć:

Jeśli używasz obiektu, który uzyskuje dostęp do niezarządzanych zasobów, takich jak StreamWriter, dobrym rozwiązaniem jest utworzenie wystąpienia za pomocą instrukcji using . Instrukcja using automatycznie zamyka strumień i wywołuje Dispose obiekt po zakończeniu kodu, który go używa. Aby zapoznać się z przykładem, zobacz klasę StreamWriter .

Dotyczy

Produkt Wersje
.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
.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
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Zobacz też