Tuesday, September 2, 2008

Close Vs Dispose - Eternal discussion

If we compare to connection object, Dispose will also clear the connection, whereas Close will not. This means that if you close a connection and then open it, it will work OK, but if you dispose it and then open it, it will throw InvalidOperationException since the connection string is not initialized

I would always argue that you should call Dispose() on any object that implements IDisposable (as Microsoft Recomend) when you are through with the object. Even if it does nothing. The jit compiiler will optimize it out of the final code anyway(Because of finalizer thread who do the task). If the object contains a Close() but no Dispose() then call Close().

IL of the Dispose method of Connection Object

.method family hidebysig virtual instance void Dispose(bool disposing) cil managed
{
.maxstack 2
L_0000: ldarg.1
L_0001: brfalse.s L_0017
L_0003: ldarg.0
L_0004: ldnull
L_0005: stfld class System.Data.Common.DbConnectionOptions System.Data.SqlClient.SqlConnection::_userConnectionOptions
L_000a: ldarg.0
L_000b: ldnull
L_000c: stfld class System.Data.ProviderBase.DbConnectionPoolGroup System.Data.SqlClient.SqlConnection::_poolGroup
L_0011: ldarg.0
L_0012: callvirt instance void System.Data.Common.DbConnection::Close()
L_0017: ldarg.0
L_0018: ldarg.1
L_0019: call instance void System.Data.SqlClient.SqlConnection::DisposeMe(bool)
L_001e: ldarg.0
L_001f: ldarg.1
L_0020: call instance void [System]System.ComponentModel.Component::Dispose(bool)
L_0025: ret
}

Dispose of Connection Object (C#):

protected override void Dispose(bool disposing)
{
if (disposing)
{
this._userConnectionOptions = null; (make connection string = null)
this._poolGroup = null; (Remove connection from connection pool)
this.Close(); (Close connection)
}
this.DisposeMe(disposing); (Dispose Connection)
base.Dispose(disposing); (Dispose parent object)
}


_userConnectionOptions is effectively the processed connection string as theprovider uses it internally

No comments: