Export (0) Print
Expand All

IDisposable Interface

Provides a mechanism for releasing unmanaged resources.

To browse the .NET Framework source code for this type, see the Reference Source.

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

'Declaration
<ComVisibleAttribute(True)> _
Public Interface IDisposable

The IDisposable type exposes the following members.

  NameDescription
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsDisposePerforms application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Top

NoteNote

To view the .NET Framework source code for this type, see the Reference Source. You can browse through the source code online, download the reference for offline viewing, and step through the sources (including patches and updates) during debugging; see instructions.

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.

Caution noteCaution

It is a breaking change to add the IDisposable interface to an existing class. Because pre-existing consumers of your type cannot call Dispose, you cannot be certain that unmanaged resources held by your type will be released.

Because the IDisposable.Dispose implementation is called by the consumer of a type when the resources owned by an instance are no longer needed, you should either wrap the managed object in a SafeHandle (the recommended alternative), or you should override Object.Finalize to free unmanaged resources in the event that the consumer forgets to call Dispose.

Important noteImportant

In the .NET Framework, the C++ compiler supports deterministic disposal of resources and does not allow direct implementation of the Dispose method.

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.

Using an object that implements IDisposable

Implement IDisposable only if you are using unmanaged resources directly. If your app simply uses an object that implements IDisposable, don't provide an IDisposable implementation. Instead, you should call the object's IDisposable.Dispose implementation when you are finished using it. Depending on your programming language, you can do this in one of two ways:

  • By using a language construct such as the using statement in C# and Visual Basic.

  • By wrapping the call to the IDisposable.Dispose implementation in a try/catch block.

NoteNote

Documentation for types that implement IDisposable note that fact and include a reminder to call its Dispose implementation.

If your language supports a construct such as the using statement in C# and the Using statement in Visual Basic, you can use it instead of explicitly calling IDisposable.Dispose yourself. The following example uses this approach in defining a WordCount class that preserves information about a file and the number of words in it.

Imports System.IO
Imports System.Text.RegularExpressions

Public Class WordCount
   Private filename As String 
   Private nWords As Integer 
   Private pattern As String = "\b\w+\b"  

   Public Sub New(filename As String)
      If Not File.Exists(filename) Then 
         Throw New FileNotFoundException("The file does not exist.")
      End If    

      Me.filename = filename
      Dim txt As String = String.Empty
      Using sr As New StreamReader(filename)
         txt = sr.ReadToEnd()
      End Using
      nWords = Regex.Matches(txt, pattern).Count
   End Sub 

   Public ReadOnly Property FullName As String 
      Get 
         Return filename
      End Get    
   End Property 

   Public ReadOnly Property Name As String 
      Get 
         Return Path.GetFileName(filename)
      End Get    
   End Property 

   Public ReadOnly Property Count As Integer 
      Get 
         Return nWords
      End Get 
   End Property 
End Class

The using statement is actually a syntactic convenience. At compile time, the language compiler implements the intermediate language (IL) for a try/catch block.

For more information about the using statement, see the Using Statement (Visual Basic) or using Statement (C# Reference) topics.

If your programming language does not support a construct like the using statement in C# or Visual Basic, or if you prefer not to use it, you can call the IDisposable.Dispose implementation from the finally block of a try/catch statement. The following example replaces the using block in the previous example with a try/catch/finally block.

Imports System.IO
Imports System.Text.RegularExpressions

Public Class WordCount
   Private filename As String 
   Private nWords As Integer 
   Private pattern As String = "\b\w+\b"  

   Public Sub New(filename As String)
      If Not File.Exists(filename) Then 
         Throw New FileNotFoundException("The file does not exist.")
      End If    

      Me.filename = filename
      Dim txt As String = String.Empty
      Dim sr As StreamReader = Nothing 
      Try
         sr = New StreamReader(filename)
         txt = sr.ReadToEnd()
      Finally 
         If sr IsNot Nothing Then sr.Dispose() 
      End Try
      nWords = Regex.Matches(txt, pattern).Count
   End Sub 

   Public ReadOnly Property FullName As String 
      Get 
         Return filename
      End Get    
   End Property 

   Public ReadOnly Property Name As String 
      Get 
         Return Path.GetFileName(filename)
      End Get    
   End Property 

   Public ReadOnly Property Count As Integer 
      Get 
         Return nWords
      End Get 
   End Property 
End Class

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

Implementing IDisposable

You should implement IDisposable only if your type uses unmanaged resources directly. The consumers of your type can call your IDisposable.Dispose implementation to free resources when the instance is no longer needed. To handle cases in which they fail to call Dispose, you should either use a class derived from SafeHandle to wrap the unmanaged resources, or you should override the Object.Finalize method for a reference type. In either case, you use the Dispose method to perform whatever cleanup is necessary after using the unmanaged resources, such as freeing, releasing, or resetting the unmanaged resources.

Important noteImportant

If you are defining a base class that uses unmanaged resources and that either has, or is likely to have, subclasses that should be disposed, you should implement the IDisposable.Dispose method and provide a second overload of Dispose, as discussed in the next section.

IDisposable and the inheritance hierarchy

A base class with subclasses that should be disposable must implement IDisposable as follows. You should use this pattern whenever you implement IDisposable on any type that isn't sealed (NotInheritable in Visual Basic).

  • It should provide one public, non-virtual Dispose method and a protected virtual Dispose(Boolean disposing) method.

  • The Dispose method must call Dispose(true) and should suppress finalization for performance.

  • The base type should not include any finalizers.

The following code fragment reflects the dispose pattern for base classes. It assumes that your type does not override the Object.Finalize method.

Class BaseClass : Implements IDisposable
   ' Flag: Has Dispose already been called? 
   Dim disposed As Boolean = False 

   ' Public implementation of Dispose pattern callable by consumers. 
   Public Sub Dispose() _
              Implements IDisposable.Dispose
      Dispose(True)
      GC.SuppressFinalize(Me)           
   End Sub 

   ' Protected implementation of Dispose pattern. 
   Protected Overridable Sub Dispose(disposing As Boolean)
      If disposed Then Return 

      If disposing Then 
         ' Free any other managed objects here. 
         
      End If 

      ' Free any unmanaged objects here. 
      '
      disposed = True 
   End Sub 
End Class

If you do override the Object.Finalize method, your class should implement the following pattern.

Class BaseClass : Implements IDisposable
   ' Flag: Has Dispose already been called? 
   Dim disposed As Boolean = False 

   ' Public implementation of Dispose pattern callable by consumers. 
   Public Sub Dispose() _
              Implements IDisposable.Dispose
      Dispose(True)
      GC.SuppressFinalize(Me)           
   End Sub 

   ' Protected implementation of Dispose pattern. 
   Protected Overridable Sub Dispose(disposing As Boolean)
      If disposed Then Return 

      If disposing Then 
         ' Free any other managed objects here. 
         
      End If 

      ' Free any unmanaged objects here. 
      '
      disposed = True 
   End Sub 

   Protected Overrides Sub Finalize()
      Dispose(False)      
   End Sub 
End Class

Subclasses should implement the disposable pattern as follows:

  • They must override Dispose(Boolean) and call the base class Dispose(Boolean) implementation.

  • They can provide a finalizer if needed. The finalizer must call Dispose(false).

Note that derived classes do not themselves implement the IDisposable interface and do not include a parameterless Dispose method. They only override the base class Dispose(Boolean) method.

The following code fragment reflects the dispose pattern for derived classes. It assumes that your type does not override the Object.Finalize method.

Class DerivedClass : Inherits BaseClass 
   ' Flag: Has Dispose already been called? 
   Dim disposed As Boolean = False 

   ' Protected implementation of Dispose pattern. 
   Protected Overrides Sub Dispose(disposing As Boolean)
      If disposed Then Return 

      If disposing Then 
         ' Free any other managed objects here. 
         
      End If 

      ' Free any unmanaged objects here. 
      '
      disposed = True 

      ' Call base class implementation. 
      MyBase.Dispose(disposing)
   End Sub 
End Class

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

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

.NET Framework

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

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Portable Class Library

Supported in: Portable Class Library

.NET for Windows Store apps

Supported in: Windows 8

.NET for Windows Phone apps

Supported in: Windows Phone 8.1, Windows Phone Silverlight 8.1, Windows Phone Silverlight 8

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

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

Show:
© 2014 Microsoft