unmanaged vs: managed code dispose method

  • Thread starter Thread starter Herman
  • Start date Start date
H

Herman

I'm using SQL Server from a Web App built with VB.Net
2003. I researched Garbage Collection and the Dispose
method. .Net 2003 Help, sqlconnection class, ms-
help://MS.VSCC.2003/MS.MSDNQTR.2004JAN.1033/cpref/html/frlr
fsystemdatasqlclientsqlconnectionclasstopic.htm, says this.
If the SqlConnection goes out of scope, it is not closed.
Therefore, you must explicitly close the connection by
calling Close or Dispose.
Sqlconnection uses unmanaged code.

The Close method help states;
Do not call Close or Dispose on a Connection, a
DataReader, or any other managed object in the Finalize
method of your class. In a finalizer, you should only
release unmanaged resources that your class owns directly.
If your class does not own any unmanaged resources, do not
include a Finalize method in your class definition. For
more information, see Programming for Garbage Collection.

This says that the SqlConnection is managed. I found
experts writing that the dispose method should be used if
available.

Which method should be used for the best scalability and
performance?
 
Herman,
I am the one that had the Caution not about not calling close or dispose on
a finalizer so I apologize if it is not clear. I added this caution after
looking into one too many stress related issues with SqlConnections on
Finalizers.

You must call either Close or Dispose (or both) on the SqlConnection, but
you cannot do it on a Finalizer. When using C# it is recommended that you
rely on the "using" keyword, if not you can use a
try{...}finally{.Close/.Dispose} block. The "using" or the "finally" block
guarantee that Close or Dispose will get called even if there is an
exception that throws out of the current context.

As far as which one to use, Close or Dispose (or Both) here is the relevant
IL for Dispose (use the ildasm utility that ships with the SDK to look at
system.data.dll SqlConnection Dispose)

IL_0004: ldfld valuetype System.Data.ConnectionState
System.Data.SqlClient.SqlConnection::_objectState //if Connection state is
open

IL_001b: call instance void System.Data.SqlClient.SqlConnection::Close()
//this is the public Close method!

IL_0022: stfld class System.Data.SqlClient.SqlConnectionString
System.Data.SqlClient.SqlConnection::_constr //Cleans up the
SqlConnectionString

IL_0029: call instance void
[System]System.ComponentModel.Component::Dispose(bool) //mostly a no-op


As you can see we are Checking the State of the SqlConnection, if it is open
then we call Close(). The only real difference between Close() and Dispose()
is that Dispose cleans the SqlConnectionString and calls Component Dispose
(which does not really do anything). If you call both Close() and then
Dispose() you are getting a total perf hit of one (If connection.state is
closed ) call.


Hope this helps
 
Hi Herman,

With connection it doesn't matter - either will do.
Which method to call - it depends, normally after Close you can still Open
using the same instance.
While after Dispose the instance is ... disposed.
 
Miha,
While after Dispose the instance is ... disposed.

This is actually the problem with this object, the instance is not Disposed
since it is only a wrapper.
The only thing that happens is that Close gets called and the Connection
String is cleared. Give the connection a new connection string and you can
open it and use at will.

SqlConnection sqlconnection1 = new SqlConnection(myConnectionString);
sqlconnection1.Open();
sqlconnection1.Dispose();
sqlconnection1.ConnectionString = myConnectionString2;
sqlconnection1.Open(); //this works fine
 
Hi Angel,


Angel Saenz-Badillos said:
Miha,

This is actually the problem with this object, the instance is not Disposed
since it is only a wrapper.
The only thing that happens is that Close gets called and the Connection
String is cleared. Give the connection a new connection string and you can
open it and use at will.

Yes, you are right. However Dispose acts also on Component.Dispose which
removes the instance from site Container if that matters (I guess it does
sometimes).
 
Thank you for your answer. I'm still a little foggy on
managed vs: unmanaged resources.

In VB.net (2003), the SqlCommand also has the dispose
method. Should it also be called ? Is there a reasonable
way to verify if a class's dispose method needs to be
called? I noticed that many controls used in web forms
have a dispose method. Should I just let the GC take care
of them? I dispose of any object that has the dispose
method if I create it at run time. I don't dispose design
time objects.
 
Hi Herman,

Herman said:
Thank you for your answer. I'm still a little foggy on
managed vs: unmanaged resources.

In VB.net (2003), the SqlCommand also has the dispose
method. Should it also be called ?

No.

Is there a reasonable
way to verify if a class's dispose method needs to be
called?

Only by reading documentation or peeking into code.

I noticed that many controls used in web forms
have a dispose method. Should I just let the GC take care
of them? I dispose of any object that has the dispose
method if I create it at run time. I don't dispose design
time objects.

You should dispose (or call Close method) on objects that documentation
states that it is necessary.
 
Hi Angel,

I just want to get your view on this. Miha already
answered this.

Thank you for your answer. I'm still a little foggy on
managed vs: unmanaged resources.

In VB.net (2003), the SqlCommand also has the dispose
method. Should it also be called ? Is there a reasonable
way to verify if a class's dispose method needs to be
called? I noticed that many controls used in web forms
have a dispose method. Should I just let the GC take care
of them? I dispose of any object that has the dispose
method if I create it at run time. I don't dispose design
time objects. Is this wasted resources?


-----Original Message-----
Herman,
I am the one that had the Caution not about not calling close or dispose on
a finalizer so I apologize if it is not clear. I added this caution after
looking into one too many stress related issues with SqlConnections on
Finalizers.

You must call either Close or Dispose (or both) on the SqlConnection, but
you cannot do it on a Finalizer. When using C# it is recommended that you
rely on the "using" keyword, if not you can use a
try{...}finally{.Close/.Dispose} block. The "using" or the "finally" block
guarantee that Close or Dispose will get called even if there is an
exception that throws out of the current context.

As far as which one to use, Close or Dispose (or Both) here is the relevant
IL for Dispose (use the ildasm utility that ships with the SDK to look at
system.data.dll SqlConnection Dispose)

IL_0004: ldfld valuetype System.Data.ConnectionState
System.Data.SqlClient.SqlConnection::_objectState //if Connection state is
open

IL_001b: call instance void System.Data.SqlClient.SqlConnection::Close()
//this is the public Close method!

IL_0022: stfld class System.Data.SqlClient.SqlConnectionString
System.Data.SqlClient.SqlConnection::_constr //Cleans up the
SqlConnectionString

IL_0029: call instance void
[System]System.ComponentModel.Component::Dispose (bool) //mostly a no-op


As you can see we are Checking the State of the SqlConnection, if it is open
then we call Close(). The only real difference between Close() and Dispose()
is that Dispose cleans the SqlConnectionString and calls Component Dispose
(which does not really do anything). If you call both Close() and then
Dispose() you are getting a total perf hit of one (If connection.state is
closed ) call.


Hope this helps

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.

Herman said:
I'm using SQL Server from a Web App built with VB.Net
2003. I researched Garbage Collection and the Dispose
method. .Net 2003 Help, sqlconnection class, ms-
help://MS.VSCC.2003/MS.MSDNQTR.2004JAN.1033/cpref/html/frlr
fsystemdatasqlclientsqlconnectionclasstopic.htm, says this.
If the SqlConnection goes out of scope, it is not closed.
Therefore, you must explicitly close the connection by
calling Close or Dispose.
Sqlconnection uses unmanaged code.

The Close method help states;
Do not call Close or Dispose on a Connection, a
DataReader, or any other managed object in the Finalize
method of your class. In a finalizer, you should only
release unmanaged resources that your class owns directly.
If your class does not own any unmanaged resources, do not
include a Finalize method in your class definition. For
more information, see Programming for Garbage Collection.

This says that the SqlConnection is managed. I found
experts writing that the dispose method should be used if
available.

Which method should be used for the best scalability and
performance?


.
 
My view on this is more aggressive, in general if an object implements
IDisposable it is recommended that you call Dispose on it. There is no harm
in following this strategy even on objects like the v1.1 SqlCommand where
Dispose is a no-op, there could be some benefits (in v2.0 alpha of the
SqlCommand Dispose is no longer a no-op. This may change before the beta
release but it shows that peeking into code may not be enough in the long
run)

If you are using c# I would recommend that you rely on the "using" statement
to dispose your IDisposable objects, in VB.net you can use the try finally
syntax. In the case of the SqlConnection this is more a requirement than a
recommendation imho.
Hope this helps,

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.

Herman said:
Hi Angel,

I just want to get your view on this. Miha already
answered this.

Thank you for your answer. I'm still a little foggy on
managed vs: unmanaged resources.

In VB.net (2003), the SqlCommand also has the dispose
method. Should it also be called ? Is there a reasonable
way to verify if a class's dispose method needs to be
called? I noticed that many controls used in web forms
have a dispose method. Should I just let the GC take care
of them? I dispose of any object that has the dispose
method if I create it at run time. I don't dispose design
time objects. Is this wasted resources?


-----Original Message-----
Herman,
I am the one that had the Caution not about not calling close or dispose on
a finalizer so I apologize if it is not clear. I added this caution after
looking into one too many stress related issues with SqlConnections on
Finalizers.

You must call either Close or Dispose (or both) on the SqlConnection, but
you cannot do it on a Finalizer. When using C# it is recommended that you
rely on the "using" keyword, if not you can use a
try{...}finally{.Close/.Dispose} block. The "using" or the "finally" block
guarantee that Close or Dispose will get called even if there is an
exception that throws out of the current context.

As far as which one to use, Close or Dispose (or Both) here is the relevant
IL for Dispose (use the ildasm utility that ships with the SDK to look at
system.data.dll SqlConnection Dispose)

IL_0004: ldfld valuetype System.Data.ConnectionState
System.Data.SqlClient.SqlConnection::_objectState //if Connection state is
open

IL_001b: call instance void System.Data.SqlClient.SqlConnection::Close()
//this is the public Close method!

IL_0022: stfld class System.Data.SqlClient.SqlConnectionString
System.Data.SqlClient.SqlConnection::_constr //Cleans up the
SqlConnectionString

IL_0029: call instance void
[System]System.ComponentModel.Component::Dispose (bool) //mostly a no-op


As you can see we are Checking the State of the SqlConnection, if it is open
then we call Close(). The only real difference between Close() and Dispose()
is that Dispose cleans the SqlConnectionString and calls Component Dispose
(which does not really do anything). If you call both Close() and then
Dispose() you are getting a total perf hit of one (If connection.state is
closed ) call.


Hope this helps

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.

Herman said:
I'm using SQL Server from a Web App built with VB.Net
2003. I researched Garbage Collection and the Dispose
method. .Net 2003 Help, sqlconnection class, ms-
help://MS.VSCC.2003/MS.MSDNQTR.2004JAN.1033/cpref/html/frlr
fsystemdatasqlclientsqlconnectionclasstopic.htm, says this.
If the SqlConnection goes out of scope, it is not closed.
Therefore, you must explicitly close the connection by
calling Close or Dispose.
Sqlconnection uses unmanaged code.

The Close method help states;
Do not call Close or Dispose on a Connection, a
DataReader, or any other managed object in the Finalize
method of your class. In a finalizer, you should only
release unmanaged resources that your class owns directly.
If your class does not own any unmanaged resources, do not
include a Finalize method in your class definition. For
more information, see Programming for Garbage Collection.

This says that the SqlConnection is managed. I found
experts writing that the dispose method should be used if
available.

Which method should be used for the best scalability and
performance?


.
 
Back
Top