IDisposable.Dispose Metódus

Definíció

Végrehajtja a nem felügyelt erőforrások felszabadításával, felszabadításával vagy alaphelyzetbe állításával kapcsolatos alkalmazásalapú feladatokat.

public:
 void Dispose();
public void Dispose();
abstract member Dispose : unit -> unit
Public Sub Dispose ()

Példák

Az alábbi példa bemutatja, hogyan implementálhatja a metódust Dispose .

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

Megjegyzések

Ezzel a módszerrel bezárhatja vagy felszabadíthatja a nem felügyelt erőforrásokat, például a fájlokat, streameket és kezelőket, amelyeket az ezen felületet megvalósító osztály egy példánya tárol. Ez a módszer konvenció szerint minden olyan tevékenységhez használatos, amely egy objektum erőforrásainak felszabadításával vagy egy objektum újbóli használatra való előkészítésével kapcsolatos.

Warning

Ha olyan osztályt használ, amely implementálja az IDisposable interfészt, akkor az osztály használatának befejezésekor hívja meg annak implementációját Dispose . További információ: Az IDisposable-t megvalósító objektum használata.

A metódus megvalósításakor győződjön meg arról, hogy az összes tárolt erőforrás felszabadítható a hívás elszigetelési hierarchián keresztüli propagálásával. Ha például egy A objektum lefoglal egy B objektumot, a B objektum pedig egy C objektumot foglal le, akkor az A implementációjának Dispose a B-t kell meghívnia Dispose , amelynek viszont C-t kell hívnia Dispose .

Az objektumnak az Dispose alaposztály metódusát is meg kell hívnia, ha az alaposztály implementálva van IDisposable. Az alaposztály és alosztályai implementálásával IDisposable kapcsolatos további információkért lásd az IDisposable és az öröklési hierarchia című témakört.

Ha egy objektum Dispose metódusa többször van meghívva, az objektumnak figyelmen kívül kell hagynia az első utáni összes hívást. Az objektum nem hozhat kivételt, ha a Dispose metódust többször is meghívják. Az erőforrások már elidegenítésének időpontjától Dispose eltérő példánymetelyek is eldobhatók ObjectDisposedException .

A felhasználók elvárhatják, hogy egy erőforrástípus egy adott konvencióval jelöljön ki egy lefoglalt állapotot és egy felszabadított állapotot. Erre példa a streamosztályok, amelyeket hagyományosan nyitottnak vagy bezártnak gondolnak. Egy ilyen konvencióval rendelkező osztály implementálója dönthet úgy, hogy testre szabott néven implementál egy nyilvános metódust, például Closemeghívja a metódust Dispose .

Mivel a Dispose metódust explicit módon kell meghívni, mindig fennáll a veszélye annak, hogy a nem felügyelt erőforrások nem lesznek felszabadítva, mert egy objektum felhasználója nem hívja meg a metódust Dispose . Ezt kétféleképpen lehet elkerülni:

  • A felügyelt erőforrás körbefuttatása egy, a forrásból származtatott objektumba System.Runtime.InteropServices.SafeHandle. A Dispose megvalósítás ezután meghívja a Dispose példányok metódusát System.Runtime.InteropServices.SafeHandle . További információ: The SafeHandle alternative.
  • Véglegesítő implementálása az erőforrások felszabadításához, ha Dispose nincs meghívva. Alapértelmezés szerint a szemétgyűjtő automatikusan meghívja az objektum véglegesítőjét, mielőtt visszanyeri a memóriáját. Ha azonban a Dispose metódust meghívták, általában szükségtelen, hogy a szemétgyűjtő meghívja az elvetett objektum véglegesítőjét. Az automatikus véglegesítés megakadályozása érdekében a Dispose implementációk meghívhatják a metódust GC.SuppressFinalize .

Ha olyan objektumot használ, amely nem felügyelt erőforrásokhoz fér hozzá,például egy StreamWriter, akkor érdemes utasítással létrehozni a példányt using . Az using utasítás automatikusan bezárja a streamet, és meghívja Dispose az objektumot, amikor az azt használó kód befejeződött. Például tekintse meg az osztályt StreamWriter .

A következőre érvényes:

Lásd még