Ten artykuł został przetłumaczony przez maszynę. Aby wyświetlić jego treść w języku angielskim, zaznacz pole wyboru Angielski. Możesz też wyświetlić angielski tekst w okienku wyskakującym, przesuwając wskaźnik myszy nad konkretny tekst”.
Tłumaczenie
Angielski

Interfejs IDisposable

.NET Framework (current version)
 

Data opublikowania: sierpień 2016

Udostępnia mechanizm służący do zwalniania niezarządzanych zasobów.

Aby przejrzeć kod źródłowy .NET Framework dla tego typu, zobacz Reference Source.

Przestrzeń nazw:   System
Zestaw:  mscorlib (w mscorlib.dll)

[ComVisibleAttribute(true)]
public interface IDisposable

NazwaOpis
System_CAPS_pubmethodDispose()

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

System_CAPS_noteUwaga

Aby wyświetlić kod źródłowy .NET Framework dla tego typu, zobacz Reference Source. Można przejrzeć kod źródłowy w tryb online, Pobierz odwołanie do wyświetlenia w trybie offline i kroków opisanych źródeł (w tym poprawek i aktualizacji) podczas debugowania. see instructions.

Podstawowym zastosowaniem tego interfejsu jest, aby zwolnić zasoby niezarządzane. Moduł zbierający elementy bezużyteczne automatycznie zwalnia pamięć przydzielona do zarządzanego obiektu, gdy obiekt jest już używany. Jednak nie jest możliwe do przewidzenia, gdy nastąpi wyrzucanie elementów bezużytecznych. Ponadto moduł garbage collector nie zna niezarządzane zasoby, takie jak dojścia do okna lub Otwórz pliki i strumienie.

Użyj Dispose metoda jawnie zwolnić niezarządzane zasoby w połączeniu z modułu zbierającego elementy bezużyteczne w tym interfejsie. Tę metodę można wywołać obiektu konsumenta, gdy obiekt jest już potrzebne.

System_CAPS_warningOstrzeżenie

Jest to istotne zmiany, aby dodać IDisposable interfejs do istniejącej klasy. Ponieważ już istniejących konsumentów tego typu nie można wywołać Dispose, nie można mieć pewności, zostaną zwolnione niezarządzane zasoby zajmowane przez danego typu.

Ponieważ IDisposable.Dispose implementacji jest wywoływana przez użytkownika typu zasobów należących do wystąpienia są już potrzebne, albo zawijania obiektu zarządzanego w SafeHandle (zalecaną alternatywą) lub powinny zastępować Object.Finalize do zwalniania niezarządzanych zasobów, w przypadku, gdy użytkownik zapomni do wywołania Dispose.

System_CAPS_importantWażne

W programie .NET Framework kompilatora C++ obsługuje usuwania deterministyczne zasobów i nie zezwala na bezpośredniej implementacji elementów Dispose metody.

Szczegółowe omówienie o tym, jak ten interfejs i Object.Finalize są używane metody, zobacz Odzyskiwanie pamięci i Implementacja metody Dispose tematów.

Implementowanie IDisposable tylko wtedy, gdy używasz zasobów niezarządzanych bezpośrednio. Jeśli aplikacja korzysta z po prostu obiekt, który implementuje IDisposable, nie udostępniają IDisposable implementacji. Zamiast tego należy wywołać obiektu IDisposable.Dispose implementacji po zakończeniu korzystania z niego. W zależności od języka programowania można to zrobić na dwa sposoby:

  • Przy użyciu języka takich jak utworzyć using instrukcji w języku C# i Visual Basic.

  • Zawijania wywołanie IDisposable.Dispose implementacja try/catch bloku.

System_CAPS_noteUwaga

Dokumentację dla typów, które implementują IDisposable należy pamiętać, że faktów i dołączyć przypomnienie wywołać jej Dispose implementacji.

Jeśli język obsługuje konstrukcję, takich jak przy użyciu instrukcji w języku C# i Using instrukcji w języku Visual Basic, służy zamiast jawnie podczas wywoływania IDisposable.Dispose samodzielnie. Poniższy przykład korzysta z tej metody w definiowanie WordCount klasy, która zachowuje informacje o pliku i liczbę słów w nim.

using System;
using System.IO;
using System.Text.RegularExpressions;

public class WordCount
{
   private String filename = String.Empty;
   private int nWords = 0;
   private String pattern = @"\b\w+\b"; 

   public WordCount(string filename)
   {
      if (! File.Exists(filename))
         throw new FileNotFoundException("The file does not exist.");

      this.filename = filename;
      string txt = String.Empty;
      using (StreamReader sr = new StreamReader(filename)) {
         txt = sr.ReadToEnd();
      }
      nWords = Regex.Matches(txt, pattern).Count;
   }

   public string FullName
   { get { return filename; } }

   public string Name
   { get { return Path.GetFileName(filename); } }

   public int Count 
   { get { return nWords; } }
}   

using Instrukcja jest rzeczywiście składniowe udogodnienie. W czasie kompilacji, kompilator języka implementuje języku pośrednim (IL) dla try/catch bloku.

Aby uzyskać więcej informacji na temat using instrukcji, zobacz Using — Instrukcja (Visual Basic) lub using — Instrukcja (odwołanie w C#) tematów.

Jeśli język programowania nie obsługuje konstrukcji, takich jak using instrukcji w języku C# lub Visual Basic, lub jeśli nie chcesz jej użyć, należy wywołać IDisposable.Dispose implementację z finally zablokować z try/catch instrukcji. W poniższym przykładzie using blok w poprzednim przykładzie z try/catch/finally bloku.

using System;
using System.IO;
using System.Text.RegularExpressions;

public class WordCount
{
   private String filename = String.Empty;
   private int nWords = 0;
   private String pattern = @"\b\w+\b"; 

   public WordCount(string filename)
   {
      if (! File.Exists(filename))
         throw new FileNotFoundException("The file does not exist.");

      this.filename = filename;
      string txt = String.Empty;
      StreamReader sr = null;
      try {
         sr = new StreamReader(filename);
         txt = sr.ReadToEnd();
      }
      finally {
         if (sr != null) sr.Dispose();     
      }
      nWords = Regex.Matches(txt, pattern).Count;
   }

   public string FullName
   { get { return filename; } }

   public string Name
   { get { return Path.GetFileName(filename); } }

   public int Count 
   { get { return nWords; } }
}   

Aby uzyskać więcej informacji na temat try/finally wzorca, zobacz Try...Catch...Finally — Instrukcja (Visual Basic), try-finally (odwołanie w C#), lub try-finally — instrukcja (C).

Należy zaimplementować IDisposable tylko wtedy, gdy bezpośrednio z danym typem używa zasoby niezarządzane. Konsumenci tego typu można wywołać z IDisposable.Dispose implementacji, aby zwolnić zasoby, gdy wystąpienie jest już potrzebne. Do obsługi przypadków, w których się one zakończyć niepowodzeniem do wywołania Dispose, należy albo użyj klasą pochodną SafeHandle opakowywać niezarządzane zasoby, lub powinny zastępować Object.Finalize metody dla typu odwołania. W obu przypadkach można użyć Dispose metodę w celu niezależnie od oczyszczania jest konieczne po użyciu niezarządzane zasoby, takie jak zwalnianie zwalnianiem lub resetowaniem zasobów niezarządzanych.

System_CAPS_importantWażne

Jeśli definiujesz klasę podstawową używającą zasoby niezarządzane i który ma, albo może mieć podklas, które powinny zostać usunięte, należy zaimplementować IDisposable.Dispose — metoda i podaj drugi przeciążenia Dispose, zgodnie z opisem w następnej sekcji.

Klasa podstawowa z podklas, które powinny być usuwalne musi implementować IDisposable w następujący sposób. Należy użyć tego wzorca przy każdym zaimplementowaniem IDisposable w dowolnego typu, który nie jest sealed (NotInheritable języka Visual Basic).

  • Powinien zawierać jedno publiczne-virtual Dispose() — metoda i chronione wirtualnego Dispose(Boolean disposing) metody.

  • Dispose() Należy wywołać metodę Dispose(true) i ma pomijać finalizacji wydajności.

  • Typ podstawowy nie może zawierać żadnych finalizatory.

Poniższy fragment kodu odzwierciedla wzorzec dispose dla klas podstawowych. Przyjęto założenie, że typu nie przesłania Object.Finalize metody.

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;
   // Instantiate a SafeHandle instance.
   SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         handle.Dispose();
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }
}

Jeśli zastąpienie Object.Finalize metody, klasy powinny implementować następujące wzorca.

using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   ~BaseClass()
   {
      Dispose(false);
   }
}

Podklasy powinny implementować wzorzec rozporządzający w następujący sposób:

  • Zastępują one musi Dispose(Boolean) i Wywołaj klasę bazową Dispose(Boolean) implementacji.

  • W razie potrzeby, ich Podaj finalizator. Należy wywołać finalizatora Dispose(false).

Należy pamiętać, że klas pochodnych się implementuje IDisposable interfejsu i nie ma bezparametrowego Dispose metody. Zastępują one tylko klasę podstawową Dispose(Boolean) metody.

Poniższy fragment kodu odzwierciedla wzorzec dispose dla klas pochodnych. Przyjęto założenie, że typu nie przesłania Object.Finalize metody.

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;
   // Instantiate a SafeHandle instance.
   SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         handle.Dispose();
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //

      disposed = true;
      // Call base class implementation.
      base.Dispose(disposing);
   }
}

W poniższym przykładzie pokazano, jak utworzyć klasę zasobu, który implementuje IDisposable interfejsu.

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(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize 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# destructor syntax for finalization code.
        // This destructor will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide destructors in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.
    }
}

Platforma uniwersalna systemu Windows
Dostępne od 8
.NET Framework
Dostępne od 1.1
Biblioteka klas przenośnych
Obsługiwane w: przenośne platformy .NET
Silverlight
Dostępne od 2.0
Windows Phone Silverlight
Dostępne od 7.0
Windows Phone
Dostępne od 8.1
Powrót do początku
Pokaż: