IDisposable.Dispose 메서드

정의

관리되지 않는 리소스의 확보, 해제 또는 다시 설정과 관련된 애플리케이션 정의 작업을 수행합니다.

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

예제

다음 예제에서는 메서드를 구현하는 Dispose 방법을 보여줍니다.

#using <System.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;

// The following example demonstrates how to create a class that 
// implements the IDisposable interface and the IDisposable.Dispose
// method with finalization to clean up unmanaged resources. 
//
public ref class MyResource: public IDisposable
{
private:

   // Pointer to an external unmanaged resource.
   IntPtr handle;

   // A managed resource this class uses.
   Component^ component;

   // Track whether Dispose has been called.
   bool disposed;

public:
   // The class constructor.
   MyResource( IntPtr handle, Component^ component )
   {
      this->handle = handle;
      this->component = component;
      disposed = false;
   }

   // This method is called if the user explicitly disposes of the
   // object (by calling the Dispose method in other managed languages, 
   // or the destructor in C++). The compiler emits as a call to 
   // GC::SuppressFinalize( this ) for you, so there is no need to 
   // call it here.
   ~MyResource() 
   {
      // Dispose of managed resources.
      component->~Component();

      // Call C++ finalizer to clean up unmanaged resources.
      this->!MyResource();

      // Mark the class as disposed. This flag allows you to throw an
      // exception if a disposed object is accessed.
      disposed = true;
   }

   // Use interop to call the method necessary to clean up the 
   // unmanaged resource.
   //
   [System::Runtime::InteropServices::DllImport("Kernel32")]
   static Boolean CloseHandle( IntPtr handle );

   // The C++ finalizer destructor ensures that unmanaged resources get
   // released if the user releases the object without explicitly 
   // disposing of it.
   //
   !MyResource()
   {      
      // Call the appropriate methods to clean up unmanaged 
      // resources here. If disposing is false when Dispose(bool,
      // disposing) is called, only the following code is executed.
      CloseHandle( handle );
      handle = IntPtr::Zero;
   }

};

void main()
{
   // Insert code here to create and use the MyResource object.
   MyResource^ mr = gcnew MyResource((IntPtr) 42, (Component^) gcnew Button());
   mr->~MyResource();
}
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

설명

이 메서드를 사용하여 이 인터페이스를 구현하는 클래스 인스턴스에서 보유한 파일, 스트림 및 핸들과 같은 관리되지 않는 리소스를 닫거나 해제합니다. 규칙에 따라 이 메서드는 개체가 보유한 리소스를 해제하거나 다시 사용할 개체를 준비하는 것과 관련된 모든 작업에 사용됩니다.

경고

인터페이스를 구현 IDisposable 하는 클래스를 사용하는 경우 클래스 사용을 마치면 해당 Dispose 구현을 호출해야 합니다. 자세한 내용은 항목의 "IDisposable을 구현하는 개체 사용" 섹션을 IDisposable 참조하세요.

이 메서드를 구현할 때 포함된 모든 리소스가 포함 계층 구조를 통해 호출을 전파하여 해제되었는지 확인합니다. 예를 들어 개체 A가 개체 B를 할당하고 개체 B가 개체 C를 할당하는 경우 A의 Dispose 구현은 B를 호출 Dispose 해야 하며, 이 경우 C를 호출 Dispose 해야 합니다.

중요

C++ 컴파일러는 리소스의 결정적 폐기를 지원하며 메서드의 직접 구현을 Dispose 허용하지 않습니다.

또한 기본 클래스가 구현하는 Dispose 경우 개체는 해당 기본 클래스의 메서드를 IDisposable호출해야 합니다. 기본 클래스 및 해당 하위 클래스에서 구현하는 IDisposable 방법에 대한 자세한 내용은 항목의 "IDisposable 및 상속 계층 구조" 섹션을 IDisposable 참조하세요.

개체의 Dispose 메서드가 두 번 이상 호출되는 경우 개체는 첫 번째 호출 이후의 모든 호출을 무시해야 합니다. 메서드가 여러 번 호출되는 경우 개체가 예외를 Dispose throw해서는 안됩니다. 리소스가 이미 삭제된 경우를 throw할 ObjectDisposedException 수 있는 인스턴스 메서드가 아닌 Dispose 다른 메서드입니다.

사용자는 리소스 종류가 특정 규칙을 사용하여 할당된 상태와 해제된 상태를 나타낼 것으로 예상할 수 있습니다. 예를 들어 스트림 클래스는 일반적으로 열려 있거나 닫힌 것으로 간주합니다. 이러한 규칙을 가진 클래스의 구현자는 메서드를 호출하는 사용자 지정 이름(예: Close)을 사용하여 public 메서드를 Dispose 구현하도록 선택할 수 있습니다.

메서드를 Dispose 명시적으로 호출해야 하므로 개체 소비자가 메서드를 호출 Dispose 하지 못하기 때문에 관리되지 않는 리소스가 해제되지 않을 위험이 항상 있습니다. 이를 방지하는 방법에는 다음 두 가지가 있습니다.

  • 에서 파생된 개체에 관리되는 System.Runtime.InteropServices.SafeHandle리소스 래핑 Dispose 그런 다음 구현에서 인스턴스의 Dispose 메서드를 System.Runtime.InteropServices.SafeHandle 호출합니다. 자세한 내용은 항목의 "SafeHandle 대체" 섹션을 Object.Finalize 참조하세요.

  • 호출되지 않은 경우 Dispose 리소스를 해제하는 종료자를 구현합니다. 기본적으로 가비지 수집기는 메모리를 회수하기 전에 개체의 종료자를 자동으로 호출합니다. 그러나 메서드가 Dispose 호출된 경우 일반적으로 가비지 수집기에서 삭제된 개체의 종료자를 호출할 필요가 없습니다. 자동 종료 Dispose 를 방지하기 위해 구현에서 메서드를 호출할 GC.SuppressFinalize 수 있습니다.

관리되지 않는 리소스(예: 관리되지 않는 리소스)에 액세스하는 개체를 StreamWriter사용하는 경우 문을 사용하여 인스턴스 using 를 만드는 것이 좋습니다. 이 문은 using 스트림을 자동으로 닫고 사용 중인 코드가 완료되면 개체를 호출 Dispose 합니다. 예제는 클래스를 참조하세요 StreamWriter .

적용 대상

추가 정보