Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
.NET Framework 3.5
System Namespace
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
.NET Framework Class Library
IDisposable Interface

Updated: November 2007

Defines a method to release allocated resources.

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

Visual Basic (Declaration)
<ComVisibleAttribute(True)> _
Public Interface IDisposable
Visual Basic (Usage)
Dim instance As IDisposable
C#
[ComVisibleAttribute(true)]
public interface IDisposable
Visual C++
[ComVisibleAttribute(true)]
public interface class IDisposable
J#
/** @attribute ComVisibleAttribute(true) */
public interface IDisposable
JScript
public interface IDisposable

The primary use of this interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.

Use the Dispose method of this interface to explicitly release unmanaged resources in conjunction with the garbage collector. The consumer of an object can call this method when the object is no longer needed.

Important Note:

C++ programmers should read Destructors and Finalizers in Visual C++. In the .NET Framework version, the C++ compiler provides support for implementing deterministic disposal of resources and does not allow direct implementation of the Dispose method.

It is a version-breaking change to add the IDisposable interface to an existing class, because it changes the semantics of the class.

For a detailed discussion about how this interface and the Object..::.Finalize method are used, see the Garbage Collection and Implementing a Dispose Method topics.

Calling the IDisposable Interface

When calling a class that implements the IDisposable interface, use the try/finally pattern to make sure that unmanaged resources are disposed of even if an exception interrupts your application.

For more information about the try/finally pattern, see Try...Catch...Finally Statement (Visual Basic), try-finally (C# Reference), or The try-finally Statement.

Note that you can use the using statement (Using in Visual Basic) instead of the try/finally pattern. For more information, see the Using Statement (Visual Basic) documentation or the using Statement (C# Reference) documentation. 

The following example demonstrates how to create a resource class that implements the IDisposable interface.

Visual Basic
Imports System
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(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.
      Private 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(false) is optimal in terms of
         ' readability and maintainability.
         Dispose(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

C#
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.
        private 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.
    }
}

Visual C++
#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();
}

J#
import System.*;
import 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 static class MyResource implements 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 boolean 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.
        private void Dispose(boolean 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 this has been done.
                disposed = true;
            }

        } 

        // Use interop to call the method necessary  
        // to clean up the unmanaged resource.
        /** @attribute System.Runtime.InteropServices.DllImport("Kernel32")
         */
        private static native Boolean CloseHandle(IntPtr handle);

        // Use J# 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.
        public void finalize() 
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
            try {
                super.finalize();
            }
            catch(System.Exception e ) {
            }
        } 
    } //MyResource   

    public static void main(String[] args)
    {
        // Insert code here to create
        // and use the MyResource object.      
    } 
}  

Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 3.5, 2.0, 1.0

XNA Framework

Supported in: 2.0, 1.0
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Who cleans up the IDisposable object?      joniba   |   Edit   |  

How does the object itself in these examples get disposed. And also, does every managed resource that an object contains also need to have a Dispose() method?
So, in the example above:
1) In the dispose(bool) method, how do you dispose of managed resources that do not have Dispose methods? Is setting them equal to null enough?
2) If you've called the Dispose() method on your object then GC.suppressFinalize(this) also gets called, which means the GC won't clean up your object. So who cleans up object MyResource?

Tags What's this?: Add a tag
Flag as ContentBug
Re: Who cleans up the IDisposable object?      huseyint   |   Edit   |  
I am not pretty sure but from what I have understand, if you are only using managed objects (no references to unmanaged resources like File, Font, Database, etc. handles) eventually .NET Garbage Collector will release it. This is where .NET's memory management comes handy over C++/COM where you should explicitly release your objects using reference counting. My answers to your questions are:

1) Yes, if the objects you have referenced from your class implement IDisposable you should call Dispose(), otherwise you can make them null and GC will do the rest.

2) Calling GC.suppressFinalize(this) doesn't mean it will not be collected by GC. It means that there is no need to run finalizor on this object because the unmanaged resources have already been collected by calling Dispose() explicitly. This is a perf enhnacement to your class.
What's missing      drdre2005   |   Edit   |  
What is missing is how the class in the example is created and managed. It only says:
// Insert code here to create
// and use the MyResource object.

This is a half clever example since it uses both a managed (Component) and unmanaged resource (a file handle). However, I found that Dispose() itself is never called by .net. It only calls the destructor, which in turns calls Dispose(false).

The implication is that the "managed" resources will never be disposed explicitly unless the class user calls the dispose method explicitly. If this is true it would be nice to have it explained here in the example.

But that points out another source of confusion: what exactly is a managed resource? I think one point of the example is that implementing IDisposable (this way) gives your class users control over when the class' resources (managed or not) are disposed.

However, what about "managed" resources like OleDbConnection? The documentation clearly says that destroy does not close the connection. Then why didn't it implement IDisposable so that it could close its connection object (unmanaged?) when it's destroyed?

I think my code is doing the right thing, but it would be nice to have the issues I've raised clearly explained here.


Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Page view tracker