System Namespace


.NET Framework Class Library
IDisposable Interface

Defines a method to release allocated resources.

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

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
JScript
public interface IDisposable
Remarks

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

Examples

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();
}
Platforms

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, 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, Zune

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.
Version Information

.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: 3.0, 2.0, 1.0
See Also

Reference

Tags :


Community Content

joniba
Who cleans up the IDisposable object?

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 :

esazwrxre
Re: Who cleans up the IDisposable object?
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.

drdre2005
What's missing
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 :

Daniel Earwicker
"Unmanaged" Resources
I think the wording of this page needs some work. "to explicitly release unmanaged resources in conjunction with the garbage collector"? This interface works completely independently of the garbage collector.

It can be mixed in with a finalizer, but the most up-to-date advice (since 2005!) about finalizers is that you should very rarely need to write one, thanks to SafeHandle. And yet every page about IDisposable presents an example with a finalizer, as if that were the normal situation.

As a result of this, there is widespread confusion (look at any programming Q&A forum), with people claiming that any IDisposable object MUST have a finalizer, and getting seriously confused about every aspect of what is in reality the simplest interface in the whole framework.

And the extremely important value of IDisposable and the using keyword are being obscured by this.

The strangest statement on this page is the very first one: "The primary use of this interface is to release unmanaged resources."

And then the finalizer example makes it perfectly clear that Dispose can release both managed and unmanaged resources! It's the finalizer that is only allowed to release unmanaged resources (a rule that is actually an oversimplification, due to the complexity of finalization). And indeed, Dispose is extremely valuable as a way to clean up state implemented in managed code, with nothing to do with unmanaged code.

Indeed, the distinction between managed/unmanaged is irrelevant to a pure discussion of IDisposable (ignoring the niche topic of finalizers). It is not necessarily possible to tell from an API whether it is implemented in IL or C/C++/COM.

The only way to make sense of that wording is to take the phrase "unmanaged resource" as describing any resource (or program state) apart from managed memory itself. That is, anything you need to clean up where the GC is not an effective solution.

But then that would be a different meaning of "unmanaged" than is used elsewhere...
Tags : contentbug

Page view tracker