yes Virginia, SqlConnection.Dispose CALLS SqlConnection.Close

I was recently involved in an ASPAdvice thread about close and dispose – an age old .NET debate. (Okay, the “age old” part is relative.)

As backup, I quoted the msdn documentation that says “close and dispose are functionally equivalent” and someone pointed out not to believe everything I read and that in .NET 1.1, it was known to be “broken”.

With a hint from Angel Saenz-Badillos from the ADO.NET team, I opened up reflector to find proof that dispose will close as well . See the guts of dispose and close below.

I don’t see anythingn wrong with still calling close *and* dispose, just to be completely explicit. I’ve seen people do it inside of using blocks with a connection, even though the end of the block will call SqlConnection.Dispose which in turn calls close. So it’s redundant. And you would think that C# programmers would celebrate the use of less code.

Are there truly known cases where this fails?

This is SqlConnection’s Dispose method:

protected override void Dispose(bool disposing){if (disposing){this._userConnectionOptions = null;this._poolGroup = null;this.Close();}this.DisposeMe(disposing);base.Dispose(disposing);}
And just for fun…SqlConnection’s Close method. Don’t get confused by that Dispose at the end.
That’s for a different object, not the actual connection.
public override void Close(){IntPtr ptr1;Bid.ScopeEnter(out ptr1, “<sc.SqlConnection.Close|API> %d#”, this.ObjectID);try{SqlStatistics statistics1 = null;RuntimeHelpers.PrepareConstrainedRegions();try{statistics1 = SqlStatistics.StartTimer(this.Statistics);lock (this.InnerConnection){this.InnerConnection.CloseConnection(this, this.ConnectionFactory);}if (this.Statistics != null){ADP.TimerCurrent(out this._statistics._closeTimestamp);}}catch (OutOfMemoryException exception3){this.Abort(exception3);throw;}catch (StackOverflowException exception2){this.Abort(exception2);throw;}catch (ThreadAbortException exception1){this.Abort(exception1);throw;}finally{SqlStatistics.StopTimer(statistics1);}}finally{SqlDebugContext context1 = this._sdc;this._sdc = null;Bid.ScopeLeave(ref ptr1);if (context1 != null){context1.Dispose();}}}

  Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!  

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.