IDisposable.Dispose Methode
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Führt anwendungsdefinierte Aufgaben aus, die mit dem Freigeben, Freigeben oder Zurücksetzen nicht verwalteter Ressourcen verknüpft sind.
public:
void Dispose();
public void Dispose();
abstract member Dispose : unit -> unit
Public Sub Dispose ()
Beispiele
Das folgende Beispiel zeigt, wie Sie die Dispose Methode implementieren können.
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.
}
}
// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.
open System
open System.ComponentModel
open System.Runtime.InteropServices
// Use interop to call the method necessary
// to clean up the unmanaged resource.
[<DllImport "Kernel32">]
extern Boolean CloseHandle(nativeint handle)
// A base class that implements IDisposable.
// By implementing IDisposable, you are announcing that
// instances of this type allocate scarce resources.
type MyResource(handle: nativeint) =
// Pointer to an external unmanaged resource.
let mutable handle = handle
// Other managed resource this class uses.
let comp = new Component()
// Track whether Dispose has been called.
let mutable disposed = false
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
interface IDisposable with
member this.Dispose() =
this.Dispose 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.
abstract Dispose: bool -> unit
override _.Dispose(disposing) =
// Check to see if Dispose has already been called.
if not disposed then
// If disposing equals true, dispose all managed
// and unmanaged resources.
if disposing then
// Dispose managed resources.
comp.Dispose()
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle handle |> ignore
handle <- IntPtr.Zero
// Note disposing has been done.
disposed <- true
// 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.
override this.Finalize() =
// Do not re-create Dispose clean-up code here.
// Calling Dispose(disposing: false) is optimal in terms of
// readability and maintainability.
this.Dispose false
Imports 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 class that implements IDisposable.
' By implementing IDisposable, you are announcing that
' instances of this type allocate scarce resources.
Public Class MyResource
Implements IDisposable
' Pointer to an external unmanaged resource.
Private handle As IntPtr
' Other managed resource this class uses.
Private component As component
' Track whether Dispose has been called.
Private disposed As Boolean = False
' The class constructor.
Public Sub New(ByVal handle As IntPtr)
Me.handle = handle
End Sub
' Implement IDisposable.
' Do not make this method virtual.
' A derived class should not be able to override this method.
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(disposing:=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(Me)
End Sub
' 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 Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
' Check to see if Dispose has already been called.
If Not Me.disposed Then
' If disposing equals true, dispose all managed
' and unmanaged resources.
If disposing Then
' Dispose managed resources.
component.Dispose()
End If
' 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
End If
End Sub
' Use interop to call the method necessary
' to clean up the unmanaged resource.
<System.Runtime.InteropServices.DllImport("Kernel32")> _
Private Shared Function CloseHandle(ByVal handle As IntPtr) As [Boolean]
End Function
' 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 finalize methods in types derived from this class.
Protected Overrides Sub Finalize()
' Do not re-create Dispose clean-up code here.
' Calling Dispose(disposing:=False) is optimal in terms of
' readability and maintainability.
Dispose(disposing:=False)
MyBase.Finalize()
End Sub
End Class
Public Shared Sub Main()
' Insert code here to create
' and use the MyResource object.
End Sub
End Class
Hinweise
Verwenden Sie diese Methode, um nicht verwaltete Ressourcen wie Dateien, Datenströme und Handles zu schließen oder freizugeben, die von einer Instanz der Klasse gehalten werden, die diese Schnittstelle implementiert. In der Konvention wird diese Methode für alle Vorgänge verwendet, die mit dem Freigeben von Ressourcen verbunden sind, die von einem Objekt gehalten werden, oder das Vorbereiten eines Objekts für die Wiederverwendung.
Warning
Wenn Sie eine Klasse verwenden, die die IDisposable Schnittstelle implementiert, sollten Sie die Dispose Implementierung aufrufen, wenn Sie die Verwendung der Klasse abgeschlossen haben. 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 Eindämmungshierarchie verteilen. Wenn z. B. ein Objekt A ein Objekt B zuweist und Objekt B ein Objekt C zuweist, muss die Implementierung von Dispose A B aufrufen Dispose , was wiederum C aufruft Dispose .
Important
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 der Basisklasse aufrufen, wenn die Basisklasse implementiert IDisposablewird. Weitere Informationen zur Implementierung IDisposable einer Basisklasse und ihrer Unterklassen finden Sie im Abschnitt "IDisposable und die Vererbungshierarchie" im IDisposable Thema.
Wenn die Dispose-Methode eines Objekts mehrmals aufgerufen wird, muss das Objekt alle Aufrufe nach dem ersten Aufruf ignorieren. Das Objekt darf keine Ausnahme auslösen, wenn seine Dispose-Methode mehrmals aufgerufen wird. Instanzmethoden, die nicht Dispose ausgelöst ObjectDisposedException werden können, wenn Ressourcen bereits verworfen werden.
Benutzer erwarten möglicherweise, dass ein Ressourcentyp eine bestimmte Konvention verwendet, um einen zugewiesenen Zustand im Vergleich zu einem freizugebenden Zustand zu kennzeichnen. 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 entscheiden, eine öffentliche Methode mit einem angepassten Namen zu implementieren, z Close. B. mit dem Aufruf der Dispose Methode.
Da die Dispose Methode explizit aufgerufen werden muss, besteht immer die Gefahr, dass die nicht verwalteten Ressourcen nicht freigegeben werden, da der Verbraucher eines Objekts seine Dispose Methode nicht aufruft. Es gibt zwei Möglichkeiten, dies zu vermeiden:
Umschließen sie die verwaltete Ressource in einem objekt, das von System.Runtime.InteropServices.SafeHandle. Ihre Dispose Implementierung ruft dann die Dispose Methode der System.Runtime.InteropServices.SafeHandle Instanzen auf. Weitere Informationen finden Sie im Abschnitt "Die SafeHandle-Alternative" im Object.Finalize Thema.
Implementieren Sie einen Finalizer, um Ressourcen freizugeben, wenn Dispose sie nicht aufgerufen werden. Standardmäßig ruft der Garbage Collector automatisch den Finalizer eines Objekts auf, bevor er seinen Speicher zurückgibt. Wenn die Methode jedoch aufgerufen wurde, ist es in der Dispose Regel nicht erforderlich, dass der Garbage Collector den Finalizer des verworfenen Objekts aufruft. Um die automatische Fertigstellung zu verhindern, Dispose können Implementierungen die GC.SuppressFinalize Methode aufrufen.
Wenn Sie ein Objekt verwenden, das auf nicht verwaltete Ressourcen zugreift, z. B. eine StreamWriter, empfiehlt es sich, die Instanz mit einer using Anweisung zu erstellen. Die using Anweisung schließt den Datenstrom automatisch und ruft das Objekt auf Dispose , wenn der code, der es verwendet, abgeschlossen ist. Ein Beispiel finden Sie in der StreamWriter Klasse.