(0) exportieren Drucken
Alle erweitern
Dieser Artikel wurde maschinell übersetzt. Bewegen Sie den Mauszeiger über die Sätze im Artikel, um den Originaltext anzuzeigen. Weitere Informationen
Übersetzung
Original

IDisposable-Schnittstelle

Stellt einen Mechanismus für das Freigeben von nicht verwalteten Ressourcen bereit.

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

[ComVisibleAttribute(true)]
public interface IDisposable

Der IDisposable-Typ macht die folgenden Member verfügbar.

  NameBeschreibung
Öffentliche MethodeUnterstützt von XNA FrameworkUnterstützt von Portable KlassenbibliothekUnterstützt in .NET für Windows Store-AppsDisposeFührt anwendungsspezifische Aufgaben aus, die mit dem Freigeben, Zurückgeben oder Zurücksetzen von nicht verwalteten Ressourcen zusammenhängen.
Zum Seitenanfang

Über diese Schnittstelle werden hauptsächlich nicht verwaltete Ressourcen freigegeben. Der Garbage Collector gibt automatisch den für ein verwaltetes Objekt belegten Speicher frei, wenn dieses Objekt nicht mehr verwendet wird. Es kann allerdings nicht vorausgesagt werden, wann die Garbage Collection stattfindet. Darüber hinaus hat der Garbage Collector keine Kenntnis von nicht verwalteten Ressourcen wie Fensterhandles oder offenen Dateien und Streams.

Mit der Dispose-Methode dieser Schnittstelle können nicht verwaltete Ressourcen in Verbindung mit dem Garbage Collector explizit freigegeben werden. Der Consumer eines Objekts kann diese Methode aufrufen, wenn das Objekt nicht mehr benötigt wird.

WarnhinweisVorsicht

Die IDisposable-Schnittstelle zu einer existierenden Klasse hinzuzufügen ist eine versions-zerstörende Änderung, da es die Semantik der Klasse verändert.

Da die IDisposable.Dispose-Implementierung vom Consumer eines Typs aufgerufen wird, wenn die Ressourcen, die von einer Instanz verwendet werden, nicht mehr benötigt werden, sollten Sie entweder das verwaltete Objekt in SafeHandle (die empfohlene Alternative) umschließen, oder Sie sollten Object.Finalize überschreiben, um nicht verwaltete Ressourcen freigibt, im Fall, dass der Consumer vergisst, Dispose aufzurufen.

Wichtiger HinweisWichtig

C++-Programmierer sollten Destruktoren und Finalizer in Visual C++ lesen. In .NET Framework unterstützt der C++-Compiler deterministische Freigabe von Ressourcen und lässt keine direkte Implementierung der Dispose-Methode.

Eine ausführliche Beschreibung der Verwendung dieser Schnittstelle und der Object.Finalize-Methode finden Sie unter den Themen zu Garbage Collection und Implementieren einer Dispose-Methode.

Verwenden eines Objekts, die IDisposable implementiert

Implementieren Sie IDisposable nur, wenn Sie nicht verwaltete Ressourcen direkt verwenden. Wenn Ihre App einfach ein Objekt, das IDisposable implementiert, stellen Sie keine IDisposable Implementierung. Stattdessen sollten Sie die IDisposable.Dispose-Implementierung des Objekts aufrufen, wenn mit es beendet werden. Abhängig von der Programmiersprache können dies in einer von zwei Möglichkeiten:

  • Mit einem Sprachkonstrukts wie die using-Anweisung in C# und Visual Basic.

  • Durch das Umschließen des Aufrufs der IDisposable.Dispose-Implementierung in einem try/catch-Block.

HinweisHinweis

Dokumentation für Typen, die IDisposable implementieren, Hinweis den Fakten und eine Erinnerung enthalten, um Dispose aufzurufen ihre Implementierung.

aax125c9.collapse_all(de-de,VS.110).gifDie Anweisung C# und Visual Basic

Wenn die Sprachunterstützung ein Konstrukt wie die using-Anweisung in C# und Visual Basic, Sie es verwenden kann, anstatt, IDisposable.Dispose nicht explizit aufgerufen werden. Im folgenden Beispiel wird dieser Ansatz verwendet, wenn eine WordCount-Klasse definiert, die Informationen über eine Datei und Anzahl von Wörtern in ihm beibehält.


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();
         sr.Close();
      }
      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 eine syntaktische halber. Zur Kompilierzeit implementiert der Sprachcompiler die Intermediate Language (IL) für einen try/catch-Block.

Weitere Informationen zur using-Anweisung finden Sie die Themen Using-Anweisung (Visual Basic) oder using-Anweisung (C#-Referenz).

aax125c9.collapse_all(de-de,VS.110).gifDer try/catch-Block

Wenn Ihre Programmiersprache kein Konstrukt wie die using-Anweisung in C# oder Visual Basic unterstützt, oder wenn Sie es vorziehen es nicht verwendet, können Sie die IDisposable.Dispose Implementierung vom finally-Block einer try/catch-Anweisung aufgerufen. Im folgenden Beispiel using ersetzt den Block im vorherigen Beispiel durch 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();
         sr.Close();
      }
      catch {}
      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 zum try/finally-Block finden Sie unter Try...Catch...Finally-Anweisung (Visual Basic), try-finally (C#-Referenz) und try-finally-Anweisung (C).

Implementieren von IDisposable

Sie sollten IDisposable implementieren, wenn der Typ nicht verwaltete Ressourcen direkt verwendet. Die Consumer des Typs IDisposable.Dispose können die Implementierung um Ressourcen freizugeben aufrufen, wenn die Instanz nicht mehr benötigt wird. Um solche Fälle zu reagieren in der diese Dispose nicht aufrufen können, sollten Sie eine Klasse verwenden, die von SafeHandle abgeleitet wurde um die nicht verwalteten Ressourcen zu umschließen, oder Sie sollten die Object.Finalize-Methode für einen Referenztyp überschreiben. Nach Verwendung der nicht verwalteten Ressourcen, beispielsweise das Freigeben, Freigeben oder Zurücksetzen der nicht verwaltete Ressourcen, in jedem Fall verwenden Sie die Dispose-Methode, um die Bereinigung auszuführen, erforderlich ist.

Wichtiger HinweisWichtig

Wenn Sie eine Basisklasse definiert, die nicht verwaltete Ressourcen verwendet und die entweder hat, oder wahrscheinlich, über ist, Unterklassen, die freigegeben werden müssen, sollten Sie die IDisposable.Dispose-Methode implementieren und eine zweite Überladung von Dispose bereitstellen, wie im nächsten Abschnitt erläutert.

IDisposable und der Vererbungshierarchie

Eine Basisklasse mit verwerfbaren Unterklassen muss IDisposable wie folgt implementieren:

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

  • Die Dispose()-Methode muss Dispose(true) aufrufen und sollte Vervollständigung für Leistung unterdrücken.

  • Der Basistyp sollte keine Finalizer enthalten.

Das folgende Codefragment spiegelt das Dispose-Muster für Basisklassen. Dabei wird vorausgesetzt, dass der Typ nicht die Object.Finalize-Methode überschreibt.


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


Wenn Sie die Methode Object.Finalize überschreiben, sollte die Klasse 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 enthalten keine parameterlose Dispose-Methode ausführen. Sie überschreiben nur die Basisklassen Dispose(Boolean)-Methode.

Das folgende Codefragment spiegelt das Dispose-Muster für abgeleitete Klassen. Dabei wird vorausgesetzt, dass der Typ nicht die Object.Finalize-Methode überschreibt.


using System;

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

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

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

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


Im folgenden Beispiel wird das Erstellen einer Ressourcenklasse veranschaulicht, die die IDisposable-Schnittstelle verwendet.


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


.NET Framework

Unterstützt in: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Unterstützt in: 4, 3.5 SP1

Portable Klassenbibliothek

Unterstützt in: Portable Klassenbibliothek

.NET für Windows Store-Apps

Unterstützt in: Windows 8

.NET für Windows Phone-Apps

Unterstützt in: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core-Rolle wird nicht unterstützt), Windows Server 2008 R2 (Server Core-Rolle wird mit SP1 oder höher unterstützt; Itanium wird nicht unterstützt)

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen für .NET Framework.

Community-Beiträge

HINZUFÜGEN
Anzeigen:
© 2014 Microsoft