I should have said calling Dispose on the base class is irrelevant in terms of database resources.
It is relevant in terms of optimizing GC performance. The Dispose method of the base class which is the Component class suppresses Finalize on the object. If Finalize is not supressed the object takes longer to reach the point where the GC destroys it.
Public Sub Dispose()
Begin Sub
Me.Dispose(1)
GC.SuppressFinalize(Me)
End Sub
Rapidly opening and Closing thousands of SqlConnection objects (rather than disposing them bloats the GC Finalizer que. And, as we know, the longer an object lives the more likely it is moved to a different generation rather than flushed.
Disposing the connections instead would mean that the connections would never hit the GC Finalizer que. They would be destroyed much sooner. In the case of web pages they would almost never live long enough to be moved into a different GC generation.
--
Mike McIntyre
Visual Basic MVP
www.getdotnetcode.com
I agree that calling Dispose of the base class is irrelevant
Experience has shown me that calling Close vs Dispose on the SqlConnection object itself (not the base class) gives different results in Framework version 1.0x. Close has it purpose and Dispose has its purpose. Close does some but not all of the things Dispose does. Dispose does a Close and performs additional housekeeping.
With Microsoft's help we solved an issue related to this two years ago:
At aZ Software we discovered the difference between Closing and Disposing a connection object the hard way. Two+ years ago our first Vb.NET large enterprise application started leaking Windows resources when put under heavy testing by 100 end users. We were exclusively using Close on the connection object in our web pages. Within an hour we had heavy complaints and approx 75 minutes in the application crashed. Once we implemented the proper use of Close with Dispose each time a connection was no longer needed, the memory leak went away.
You have me wondering about version 1.1x. The decompiled Dispose code you provided for 1.1x is different than the decompiled Dispose code I provided for 1.0x. I also noticed that in VB.NET 2005 (unless changed by release date) that the SqlConnection's dispose method is changed again (hidden it appears).
I am also wondering if your experience is with web pages or web forms. The problem we had showed up in a web application where 100 end users were doing order entry which was generating over 3,000 connections an hour.
I will do deeper research and testing on the SqlConnection and its Close and Dispose classes on 1.0x and 1.1x. This is one of the most widely debated topics related to ADO.NET on the internet (as I am sure you know). There must be a definitive answer out there. Maybe the Marina theory is it ;-)
Ok. So looking at this code, Dispose does virtually nothing other then calling Close. It sets some internal variables to Nothing, and that's about it. We both agree that calling Dispose of the base class is not relevant here.
Here is the decompiled version of 1.1:
protected virtual void Dispose(bool disposing) {
ConnectionState local0;
if (disposing) {
local0 = this._objectState;
switch (local0)
case 1:
this.Close();
break;
this._constr = null;
}
this.Dispose(disposing);
}
So here it is very similarly, calls Close, sets a variable to null, and calls the base class Dispose.
So I am still not convinced how Dispose is any better then Close... Sorry!
Marina,
Thank you for pointing out a mistake in my post.
Where said:
Calling the Dispose method of a SqlConnection object in turn calls Close to close the connection and then Dispose on the base class to release the other unmanaged resources used by the object.
I should have written:
Calling the Dispose method of a SqlConnection object:
1. Checks to see if the connection is open and if it is it closes it.
2. Performs some resource housekeeping (see decompiled Dispose method for SqlConnection class below).
3. Calls Dispose on the base class (which does not have anything to do with the database connection).
Decompiled SqlConnection Class:
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Begin Sub
Dim state1 As ConnectionState
state1 = Me._objectState
Switch (state1)
Case 0:
goto L_0035
End Case
Case 1:
goto L_0017
End Case
End Switch
goto L_0035
L_0017:
If disposing Then
Me.Close
Me._connectionOptions = Nothing
Me._cachedOptions = Nothing
Me._connectionString = Nothing
End If
L_0035:
MyBase.Dispose(disposing)
End Sub
By the way I am referring to Framework version 1.0.3705 in my posts to this thread.
--
Mike McIntyre
Visual Basic MVP
www.getdotnetcode.com