Many people think the close () method calls the Dispose () method internally, so there is no essential difference! In fact, this view is not very accurate, for some classes, indeed close () and Dispose () there is no essential difference, but for some classes is not the case!
First, let's look at the difference between the SqlConnection close () method and the Dispose () method that we use most often:
The Dispose () method of the SqlConnection class is inherited from the component class, and the source code is this:
public void Dispose() {
Dispose(true); //调用Dispose的一个带参数的重载
GC.SuppressFinalize(this); //请求系统不要调用指定对象的终结器。
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
lock(this) {
if (site != null && site.Container != null) {
site.Container.Remove(this);
}
if (events != null) {
EventHandler handler = (EventHandler)events[EventDisposed];
if (handler != null) handler(this, EventArgs.Empty);
}
}
}
}
The close () method of the SqlConnection class is described in MSDN as follows:
Closes the connection to the database. This is the preferred method of turning off any open connections. If the SqlConnection is out of range, it is not closed. Therefore, you must explicitly turn off the connection by calling close or Dispose. Close and Dispose are functionally equivalent. If the connection pool value pooling is set to TRUE or Yes, the underlying connection is returned to the connection pool. On the other hand, if pooling is set to false or no, the underlying connection to the server is turned off.
Look at the description as if the close () method is similar to the Dispose () method, and is actually just equivalent to shutting down the connection, let's look at the source code for the closing () method:
override public void Close () {
IntPtr HSCP;
Bid.scopeenter (out HSCP, "<SC. sqlconnection.close| Api>%d# ", ObjectID);
try {
sqlstatistics statistics = NULL;
runtimehelpers.prepareconstrainedregions ();
try {
#if DEBUG
Object initialreliabilityslotvalue = Thread.getdata (Tdsparser.reliabilityslot);
runtimehelpers.prepareconstrainedregions ();
try {
Thread.setdata (Tdsparser.reliabilityslot, true);
#endif//debug
statistics = Sqlstatistics.starttimer (statistics);
//The lock is protect against the Command.cancel/connection.close
race Condition
//The Sqlinternalconnectiontds is set to Openbusy during close, once this
happens the cast below to fail and
//The command would no longer be cancelable. It might be desirable to be
able to cancel the close opperation, but this is
//Outside of the scope of Whidbey RTM. Sqlcommand::cancel for the other
lock.
Lock (innerconnection) {
Innerconnection.closeconnection (this, connectionfactory);
}
//does not require GC. KeepAlive (this) because of Onstatechange
if (null!= Statistics) {
ADP. Timercurrent (out _statistics._closetimestamp);
}
#if DEBUG
}
finally {
Thread.setdata (Tdsparser.reliabilityslot, Initialreliabilityslotvalue);
}
#endif//debug
}
catch (System.OutOfMemoryException e) {
Abort (e);
throw;
}
catch (System.StackOverflowException e) {
Abort (e);
throw;
}
catch (System.Threading.ThreadAbortException e) {
Abort (e);
throw;
}
finally {
Sqlstatistics.stoptimer (statistics);
}
}
finally {
sqldebugcontext SDC = _SDC;
_SDC = null;
Bid.scopeleave (ref HSCP);
if (SDC!= null) {
SDC. Dispose ();
}
}
}