Your try-catch looks questionable. You didn't specify where this code is being called from but you should really never call the finalizer directly in your code. You're dealing with a disposable object and that is tricky. I don't believe your existing code is correct nor does it follow the recommended pattern for cleanup.
The finalizer is called at some point before the object is released from memory. That may occur after the object has already been disposed (via a using
) so your finalizer has to handle the fact that it might already be cleaned up. Furthermore GC doesn't guarantee ordering so when the finalizer is called your connection you have may or may not have already been cleaned up. It doesn't matter that you might still have a reference to it because the GC has already determined your object isn't used anymore and therefore anything it touches is free to be cleaned up. So, in a finalizer, you cannot touch any reference type fields you might have (such as your connection) because they may not be valid anymore.
The net result is that when you are dealing with a type that has disposable resources you should follow the standard Dispose Pattern. The gist is given below with an attempt to convvert to VB.
Public Class MyClass
Implements IDisposable
Protected Override Sub Finalize ()
Dispose(False)
End Sub
Public Sub Dispose () Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose ( disposing As Boolean )
If _disposed Then
Exit Sub
End If
If disposing Then
Dim conn = m_conn
m_conn = Nothing
If conn Is Not Nothing Then
conn.Dispose()
End If
End If
_disposed = True
End Sub
Private Dim m_Conn As DbConnection
Private Dim _disposed As Boolean
End Class
The gist of this code is that when Dispose
is called either via a Using
statement or by the GC then your method is called with an indicator that it is safe to touch fields of reference types (because they are still referenced). You check to see if you need to clean them up and then have them dispose themselves. Because the object is now cleaned up you don't need the finalizer called so it is suppressed.
If the finalizer is called without Dispose
being called then the helper method is called but with an indicator that this is the finalizer and therefore reference fields cannot be touched as they may have already been cleaned up.
Note that a dispose should never crash so some people also wrap the dispose contents in a try-catch if necessary.
Finally note that an alternative approach to closing a connection is to check for the closed state and then close it but I find Dispose
easier.