Dieser Artikel wurde maschinell übersetzt. Wenn Sie die englische Version des Artikels anzeigen möchten, aktivieren Sie das Kontrollkästchen Englisch. Sie können den englischen Text auch in einem Popupfenster anzeigen, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch

IDisposable-Schnittstelle

 

Veröffentlicht: Juli 2016

Stellt einen Mechanismus für die Freigabe nicht verwalteter Ressourcen bereit.

Informationen zum Durchsuchen des .NET Framework-Quellcodes für diesen Typ finden Sie unter der Reference Source.

Namespace:   System
Assembly:  mscorlib (in mscorlib.dll)

[ComVisibleAttribute(true)]
public interface IDisposable

NameBeschreibung
System_CAPS_pubmethodDispose()

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

System_CAPS_noteHinweis

Die .NET Framework-Quellcodes für diesen Typ finden Sie unter der Reference Source. Sie können den Quellcode online Durchsuchen, Referenz für die Offlineanzeige herunterladen und schrittweise durchlaufen (inklusive Patches und Updates) während des Debuggens; see instructions.

Der primäre Verwendungszweck dieser Schnittstelle werden nicht verwaltete Ressourcen freizugeben. Automatisch freigegeben der Garbage Collector den Speicher zu einem verwalteten Objekt zugeordnet werden, wenn dieses Objekt nicht mehr verwendet wird. Allerdings ist es nicht möglich vorherzusagen, wann die Garbagecollection ausgeführt wird. Darüber hinaus wird der Garbage Collector hat keine Kenntnis von nicht verwalteten Ressourcen wie Fensterhandles oder offenen Dateien und Streams.

Verwenden der Dispose -Methode dieser Schnittstelle explizit Freigeben von nicht verwalteten Ressourcen in Verbindung mit dem Garbage Collector. Der Consumer eines Objekts kann diese Methode aufrufen, wenn das Objekt nicht mehr benötigt wird.

System_CAPS_warningWarnung

Es ist eine wichtige Änderung zum Hinzufügen der IDisposable Schnittstelle zu einer vorhandenen Klasse. Da Sie bereits vorhandene Consumer Ihres Typs nicht aufrufen können Dispose, können Sie nicht sicher, dass die nicht verwaltete Ressourcen frei, die für Ihren Typ freigegeben werden, sein.

Da die IDisposable.Dispose Implementierung vom Consumer eines Typs aufgerufen wird, wenn die Ressourcen, die im Besitz von einer Instanz nicht mehr benötigt werden, sollten Sie entweder das verwaltete Objekt im umschließen einer SafeHandle (empfohlen), oder sollten Sie überschreiben Object.Finalize auf nicht verwaltete Ressourcen freizugeben, wenn der Consumer aufrufen vergisst Dispose.

System_CAPS_importantWichtig

In .NET Framework, die C++-Compiler unterstützt deterministische Verwerfen von Ressourcen und lässt keine direkte Implementierung der der Dispose Methode.

Ausführliche Informationen dazu, wie diese Schnittstelle und die Object.Finalize Methode verwendet werden, finden Sie unter der Garbage Collection und Implementieren einer Dispose-Methode Themen.

Implementieren IDisposable nur, wenn Sie nicht verwaltete Ressourcen direkt verwendet werden. Wenn Ihre app einfach ein Objekt verwendet, die implementiert IDisposable, also ohne Angabe einer IDisposable Implementierung. Sie sollten stattdessen des Objekts aufrufen IDisposable.Dispose Implementierung, wenn Sie mit der sie fertig sind. Abhängig von der Programmiersprache möglich Sie dies auf zwei Arten:

  • Erstellen Sie mithilfe einer anderen Sprache wie z. B. die using -Anweisung in c# und Visual Basic.

  • Durch den Aufruf von umschließen die IDisposable.Dispose Implementierung in einer try/catch Block.

System_CAPS_noteHinweis

Dokumentation für Typen implementiert, IDisposable Beachten Sie den Umstand und enthalten eine Erinnerung rufen die Dispose Implementierung.

Wenn Ihre Sprache ein Konstrukt, z. B. unterstützt die mit -Anweisung in c# und die Using -Anweisung in Visual Basic können Sie sie explizit aufrufen IDisposable.Dispose selbst. Im folgenden Beispiel wird dieser Ansatz bei der Definition einer WordCount -Klasse, die Informationen zu einer Datei und die Anzahl der Wörter darin beibehalten.

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

Die using -Anweisung ist tatsächlich ein syntaktisches Hilfsmittel. Zum Zeitpunkt der Kompilierung des Sprachcompilers implementiert die intermediate Language (IL) für eine try/catch Block.

Weitere Informationen zu den using -Anweisung finden Sie unter der Using Statement (Visual Basic) oder using-Anweisung (C#-Referenz) Themen.

Wenn Ihre Programmiersprache ein Konstrukt, z. B. nicht unterstützt die using -Anweisung in c# oder Visual Basic, oder falls gewünscht, nicht, ihn zu verwenden, rufen Sie die IDisposable.Dispose Implementierung von der finally -Block ein try/catch Anweisung. Im folgende Beispiel ersetzt die using -block in dem vorhergehenden Beispiel mit einer try/catch/finally Block.

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

Weitere Informationen zu den try/finally Muster, finden Sie unter Try...Catch...Finally Statement (Visual Basic), try-finally (C#-Referenz), oder try-finally-Anweisung (C).

Implementieren Sie IDisposable nur, wenn der Typ nicht verwaltete Ressourcen direkt verwendet. Der Consumer Ihres Typs aufrufen Ihrer IDisposable.Dispose -Implementierung, die Ressourcen freizugeben, wenn die Instanz nicht mehr benötigt wird. Um Fälle zu behandeln, in dem sie nicht aufrufen Dispose, Sie sollten entweder eine Klasse abgeleitete SafeHandle Umschließen von nicht verwalteten Ressourcen, oder Sie sollten überschreiben die Object.Finalize Methode für einen Referenztyp darstellt. In beiden Fällen verwenden Sie die Dispose Methode zum Ausführen der Bereinigung erforderlich ist, nach der Verwendung von nicht verwalteten Ressourcen, z. B. Freigabe, der Zurückgabe oder dem Zurücksetzen von nicht verwalteten Ressourcen zusammenhängen.

System_CAPS_importantWichtig

Wenn Sie eine Basisklasse definieren, die verwendet nicht verwalteter Ressourcen und, hat oder verfügt wahrscheinlich über Unterklassen, die freigegeben werden sollen, implementieren Sie die IDisposable.Dispose Methode, und geben Sie eine zweite Überladung der Dispose, wie im nächsten Abschnitt erläutert.

Eine Basisklasse mit Unterklassen, die gelöscht werden sollen, muss implementieren IDisposable wie folgt. Sie sollten dieses Muster verwenden, sobald Sie implementieren IDisposable alle Typen, die nicht sealed (NotInheritable in Visual Basic).

  • Sie sollte eine öffentliche, nicht virtuelle Dispose()-Methode und eine geschützte virtuelle Dispose(Boolean disposing)-Methode bereitstellen.

  • Die Dispose() -Methodenaufruf müssen Dispose(true) und Finalisierung aus Leistungsgründen sollten unterdrücken.

  • Der Basistyp sollte keine Finalizer enthalten.

Das folgende Codefragment gibt das Dispose-Muster für Basisklassen wieder. Es wird davon ausgegangen, dass der Typ nicht überschreibt die Object.Finalize Methode.

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

Wenn Sie außer Kraft setzen die Object.Finalize -Methode die Klasse sollte das folgende Muster implementieren.

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

Unterklassen sollten das verwerfbare Muster wie folgt implementieren:

  • Sie müssen Dispose(Boolean) überschreiben und die Basisklassen-Dispose(Boolean)-Implementierung aufrufen.

  • Sie können bei Bedarf einen Finalizer bereitstellen. Der Finalizer muss Dispose(false) aufrufen.

Beachten Sie, dass abgeleitete Klassen nicht selbst implementieren die IDisposable Schnittstelle und beinhalten keine parameterlose Dispose Methode. Nur die Basisklasse überschreiben Dispose(Boolean) Methode.

Das folgende Codefragment gibt das Dispose-Muster für abgeleitete Klassen. Es wird davon ausgegangen, dass der Typ nicht überschreibt die Object.Finalize Methode.

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

Im folgenden Beispiel wird veranschaulicht, wie eine Ressourcenklasse zu erstellen, implementiert die IDisposable Schnittstelle.

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

Universelle Windows-Plattform
Verfügbar seit 8
.NET Framework
Verfügbar seit 1.1
Portierbare Klassenbibliothek
Unterstützt in: portierbare .NET-Plattformen
Silverlight
Verfügbar seit 2.0
Windows Phone Silverlight
Verfügbar seit 7.0
Windows Phone
Verfügbar seit 8.1
Zurück zum Anfang
Anzeigen: