Recipe 3.7. Releasing an Instance's Resources
Your class instance allocates resources during its lifetime, and you want to ensure that those resources are freed when the object is destroyed.
Add a Finalize( ) method to your class that includes any cleanup code you need to run before .NET destroys the class instance. Finalize() is a method included in the System.Object base class. To use it in your code, you must override it:
Protected Overrides Sub Finalize()
Because a base class from which you derive may need to perform its own cleanup, you should always call its Finalize() method:
Protected Overrides Sub Finalize() ' ----- Perform my cleanup, then… MyBase.Finalize() End Sub
.NET includes a process, known as garbage collection, which automatically releases all memory associated with a class instance. However, it doesn't know what processing is required to release any acquired external resources, such as database connections. Therefore, you must provide that logic in a special method, implemented through an override of the Finalize() method. This special method is known as the class's destructor.
The garbage collector in .NET runs as needed, so there is no guarantee that your Finalize() method will be called at the moment you release all references to an instance. It may be called one second, ten seconds, or ten minutes later, possibly long after your application has stopped running. If you need resources to be released in a timelier manner, combine the destructor with the IDisposable interface. This interface defines features that help release resources on a schedule you determine. More specifically, resources are released whenever the related Dispose() method is called on your instance. (You could simply include your own custom FreeResources() method in your class, but using IDisposable allows Visual Basic to get more involved in the cleanup process.)
To enable IDisposable in your class, add an Implements statement at the top of the class:
Class ResourceUsingClass Implements IDisposable End Class
When you add that Implements line to your class, Visual Studio automatically adds a template of features:
Class ResourceUsingClass Implements IDisposable ' To detect redundant calls Private disposedValue As Boolean = False ' IDisposable Protected Overridable Sub Dispose( _ ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then ' TODO: free unmanaged resources when ' explicitly called End If ' TODO: free shared unmanaged resources End If Me.disposedValue = True End Sub #Region " IDisposable Support " ' This code added by Visual Basic to correctly ' implement the disposable pattern. Public Sub Dispose() Implements IDisposable.Dispose ' Do not change this code. Put cleanup code in ' Dispose(ByVal disposing As Boolean) above. Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region End Class
Fill in the "TODO" parts of the code with your resource-freeing logic.
When using the IDisposable interface, you should still implement the Finalize()destructor just in case someone forgets to call Dispose(). Maintain a flag in your class that indicates whether resources have been properly freed or not. The disposedValue variable that Visual Studio generated serves this purpose.
Some Visual Basic features call Dispose() automatically when working with IDisposable-enabled objects. The Visual Basic Using statement exists to destroy objects when they are no longer needed, and it calls Dispose() automatically:
Using externalResources As New ResourceUsingClass ' ----- Work with the externalResources instance here. End Using ' ----- At this point, externalResources.Dispose has been ' called automatically by the End Using statement.
Recipe 3.6 discusses constructors, the opposite of destructors.