Tuesday, July 1, 2008

Dispose Pattern

C# Sample

public sealed class MyClass: IDisposable{
// Variable to track if Dispose has been called
private bool disposed = false;
// Implement the IDisposable.Dispose() method
public void Dispose(){
// Check if Dispose has already been called
if (!disposed) {
// Call the overridden Dispose method that contains common cleanup code
// Pass true to indicate that it is called from Dispose
Dispose(true);
// Prevent subsequent finalization of this object. This is not needed
// because managed and unmanaged resources have been explicitly released GC.SuppressFinalize(this);
}
}

// Implement a finalizer by using destructor style syntax
~MyClass() {
// Call the overridden Dispose method that contains common cleanup code
// Pass false to indicate the it is not called from Dispose
Dispose(false);
} // Implement the override Dispose method that will contain common
// cleanup functionality protected virtual void Dispose(bool disposing){ if(disposing){
// Dispose time code . . . }
// Finalize time code . . . }
…}


Passing true to the protected Dispose method ensures that dispose specific code is called. Passing false skips the Dispose specific code. The Dispose(bool) method can be called directly by your class or indirectly by the client.
If you reference any static variables or methods in your finalize-time Dispose code, make sure you check the Environment.HasShutdownStarted property. If your object is thread safe, be sure to take whatever locks are necessary for cleanup.
Use the HasShutdownStarted property in an object's Dispose method to determine whether the CLR is shutting down or the application domain is unloading. If that is the case, you cannot reliably access any object that has a finalization method and is referenced by a static field

protected virtual void Dispose(bool disposing){ if(disposing){ // dispose-time code . . . } // finalize-time code CloseHandle(); if(!Environment.HasShutDownStarted) { //Debug.Write or Trace.Write – static methods Debug.WriteLine("Finalizer Called"); } disposed = true;}

Visual Basic .NET sample

'Visual Basic .NET Code snippet

Public Class MyDispose
Implements IDisposable

Public Overloads Sub Dispose()
Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me) ' No need call finalizer
End Sub

Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)

If disposing Then
'Free managed resources

End If

' Free unmanaged resources

End Sub

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


Common disposable resources include the following:

  • Database-related classes: SqlConnection, SqlDataReader, and SqlTransaction.
  • File-based classes: FileStream and BinaryWriter.
  • Stream-based classes: StreamReader, TextReader, TextWriter, BinaryReader, and TextWriter.
  • Network-based classes: Socket, UdpClient, and TcpClient.
  • EnterpriseServices: classes that derive from System.EnterpriseServices.ServicedComponent

No comments: