As discussed at the beginning of the chapter, when a value on the heap no longer has any active references to it, the .NET Framework will eventually garbage collect the value. At the point at which a value is garbage collected off the heap, it may be desirable to perform some action such as closing an open file. When a value is garbage collected, the Framework calls the method Finalize on the value. A class can override the implementation (see Chapter 13, Inheritance, for more information on overriding) and do whatever work it needs to do.
Imports System.IO Class FileWriter Private Stream As FileStream ... Protected Overrides Sub Finalize() ' Close the stream Stream.Close() End Sub End Class
Sometimes, however, it is not sufficient to wait for the garbage collector to clean up a reference type on the heap. In the preceding example, it is possible that the FileWriter class is heavily used. Setting a variable of type FileWriter to Nothing is not sufficient to cause the file to be closed, because the garbage collector may not run for some time, depending on available memory. If the garbage collector is not run often enough, the program may run out of file handles because too many instances of FileWriter are waiting to be finalized (and, therefore, still holding on to open files). In this case, it is desirable to free up the file resource as soon as the code that created the FileWriter class is finished with it.
The System.IDisposable interface can be implemented to indicate that a reference type contains precious resources that should be disposed as soon as they are no longer needed. (See Chapter 13 for more information on interfaces.) The IDisposable interface contains a single method named Dispose , whose responsibility is to dispose of any precious resources. For example:
Imports System.IO Class FileWriter Implements IDisposable Public Stream As FileStream ... Sub Dispose() Implements IDisposable.Dispose If Not Stream Is Nothing Then Stream.Close() Stream = Nothing End If End Sub Sub New(ByVal FileName As String) Stream = New FileStream(FileName) End Sub End Class Module Test Sub Main() Dim Writer As FileWriter = New FileWriter("myfile.txt", _ FileMode.Open) Try ... Finally Writer.Dispose() End Try End Sub End Module
In this example, the FileWriter class implements the IDisposable interface, which allows the class's precious resources to be disposed of when they are no longer needed.
Dispose should be written so it can be called multiple times, so that a programmer using the class does not have to keep track of whether Dispose has already been called.
When using a disposable type, always put the call to Dispose in a Finally block. This ensures that even if an exception occurs while the class is being used, the class will still be disposed of.