PC Review


Reply
Thread Tools Rate Thread

Will this close/dispose properly?

 
 
Daniel Billingsley
Guest
Posts: n/a
 
      23rd Jun 2004
Given that
- The CloseConnection CommandBehavior of ExecuteReader causes the connection
to be "closed" when the DataReader is closed
- Close and Dispose are interchangeable on these ADO objects

1) Will the connection object in the following code get closed/disposed?

2) Since it's created in the static method of the DataFactory class but
referenced by the DataReader in the BusinessObject class, how would you
describe the scope of the connection object?

Wait - variables have scope, not objects in memory, right? So it will be
referenced both by the DataReader in the BusinessObject and the variable cn
within the scope of the GetDataReader method, right? We know when the cn
reference goes away, of course... so when the DataReader is closed then the
connection will also be closed and all will be right in the GC world.
Yes???

If possible, can you enlighten me on how you'd go about testing such a
thing, if it's possible. The DataReader doesn't expose any information
about the connection so it can't be checked through the back door that way.

============

class BusinessObject
{
public ReadData
{
using (SqlDataReader dr = DataFactory.GetDataReader()) // has some
parameters in reality
{
// extract the data from the datareader here
}
}
}

class DataFactory
{
public static SqlDataReader GetDataReader() // takes some parameters in
reality
{
SqlDataReader dr = null;
SqlConnection cn = new SqlConnection(); // with necessary parameters
cn.Open();
using (SqlCommand cm = new SqlCommand()) // with necessary parameters
{
// Set up command object
dr = cm.ExecuteReader(CommandBehavior.CloseConnection);
}
return dr;
}
}


 
Reply With Quote
 
 
 
 
Chris Taylor
Guest
Posts: n/a
 
      23rd Jun 2004
Hi Daniel,

Yes, the connection is closed when the Dispose/Close method is called on the
DataReader. I have taken the libety of including a summary description of
the key point that occur in the code.

The SqlConnection is allocated on the managed heap, so regardless of if it
was allocated by a call to a static or non-static method the object exists
on the heap and as long as it is reacheable it will not be elligeable for
collection. Since you are returning the DataReader from the GetDataReader
method, the connection is still reacheable via the reference to the Command
object which is held by the DataReader. In the case of
CommandBehaviour.CloseConnection when the DataReader is disposed at the end
of the using statement, the Connection is closed and the reference to the
Command is set to null. At this point neither the Command object nor the
Connection object are reacheable and are elligeable for collection. Of
cource since you are no longer referencing the DataReader it is also
elligeable for collection, however even if you mantained the reference to
the DataReader, the Command and Connection object are no longer reacheable
since the only surviving reference was that in the DataReader and that has
been set to null.

The best way to verify these things is to use ILDASM and take a look at what
the code is doing internally.

Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor


"Daniel Billingsley" <dbillingsley@NO_durcon_SPAAMM.com> wrote in message
news:(E-Mail Removed)...
> Given that
> - The CloseConnection CommandBehavior of ExecuteReader causes the

connection
> to be "closed" when the DataReader is closed
> - Close and Dispose are interchangeable on these ADO objects
>
> 1) Will the connection object in the following code get closed/disposed?
>
> 2) Since it's created in the static method of the DataFactory class but
> referenced by the DataReader in the BusinessObject class, how would you
> describe the scope of the connection object?
>
> Wait - variables have scope, not objects in memory, right? So it will be
> referenced both by the DataReader in the BusinessObject and the variable

cn
> within the scope of the GetDataReader method, right? We know when the cn
> reference goes away, of course... so when the DataReader is closed then

the
> connection will also be closed and all will be right in the GC world.
> Yes???
>
> If possible, can you enlighten me on how you'd go about testing such a
> thing, if it's possible. The DataReader doesn't expose any information
> about the connection so it can't be checked through the back door that

way.
>
> ============
>
> class BusinessObject
> {
> public ReadData
> {
> using (SqlDataReader dr = DataFactory.GetDataReader()) // has some
> parameters in reality
> {
> // extract the data from the datareader here
> }
> }
> }
>
> class DataFactory
> {
> public static SqlDataReader GetDataReader() // takes some parameters in
> reality
> {
> SqlDataReader dr = null;
> SqlConnection cn = new SqlConnection(); // with necessary parameters
> cn.Open();
> using (SqlCommand cm = new SqlCommand()) // with necessary

parameters
> {
> // Set up command object
> dr = cm.ExecuteReader(CommandBehavior.CloseConnection);
> }
> return dr;
> }
> }
>
>



 
Reply With Quote
 
Daniel Billingsley
Guest
Posts: n/a
 
      24th Jun 2004
Do I understand you to be suggesting that the command is not really disposed
by the using{} in the static factory: "the connection is still reacheable
via the reference to the Command object which is held by the DataReader"

Not only would I find that odd that the compiler decides the using{} will
not really work the way I expect, but also doesn't seem consistent with the
fact that if I put a using{} around the connection in the static factory I
get an error in the BO saying I can't use the DataReader on a closed
connection.

I guess my original question might be rephrased to ask if this would be
considered acceptable since I don't explicitly dispose the connection and
rely on the CloseConnection behavior to do so indirectly.

"Chris Taylor" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> Hi Daniel,
>
> Yes, the connection is closed when the Dispose/Close method is called on

the
> DataReader. I have taken the libety of including a summary description of
> the key point that occur in the code.
>
> The SqlConnection is allocated on the managed heap, so regardless of if it
> was allocated by a call to a static or non-static method the object exists
> on the heap and as long as it is reacheable it will not be elligeable for
> collection. Since you are returning the DataReader from the GetDataReader
> method, the connection is still reacheable via the reference to the

Command
> object which is held by the DataReader. In the case of
> CommandBehaviour.CloseConnection when the DataReader is disposed at the

end
> of the using statement, the Connection is closed and the reference to the
> Command is set to null. At this point neither the Command object nor the
> Connection object are reacheable and are elligeable for collection. Of
> cource since you are no longer referencing the DataReader it is also
> elligeable for collection, however even if you mantained the reference to
> the DataReader, the Command and Connection object are no longer reacheable
> since the only surviving reference was that in the DataReader and that has
> been set to null.
>
> The best way to verify these things is to use ILDASM and take a look at

what
> the code is doing internally.
>
> Hope this helps
>
> --
> Chris Taylor
> http://dotnetjunkies.com/weblog/chris.taylor
>
>
> "Daniel Billingsley" <dbillingsley@NO_durcon_SPAAMM.com> wrote in message
> news:(E-Mail Removed)...
> > Given that
> > - The CloseConnection CommandBehavior of ExecuteReader causes the

> connection
> > to be "closed" when the DataReader is closed
> > - Close and Dispose are interchangeable on these ADO objects
> >
> > 1) Will the connection object in the following code get closed/disposed?
> >
> > 2) Since it's created in the static method of the DataFactory class but
> > referenced by the DataReader in the BusinessObject class, how would you
> > describe the scope of the connection object?
> >
> > Wait - variables have scope, not objects in memory, right? So it will

be
> > referenced both by the DataReader in the BusinessObject and the variable

> cn
> > within the scope of the GetDataReader method, right? We know when the

cn
> > reference goes away, of course... so when the DataReader is closed then

> the
> > connection will also be closed and all will be right in the GC world.
> > Yes???
> >
> > If possible, can you enlighten me on how you'd go about testing such a
> > thing, if it's possible. The DataReader doesn't expose any information
> > about the connection so it can't be checked through the back door that

> way.
> >
> > ============
> >
> > class BusinessObject
> > {
> > public ReadData
> > {
> > using (SqlDataReader dr = DataFactory.GetDataReader()) // has some
> > parameters in reality
> > {
> > // extract the data from the datareader here
> > }
> > }
> > }
> >
> > class DataFactory
> > {
> > public static SqlDataReader GetDataReader() // takes some parameters

in
> > reality
> > {
> > SqlDataReader dr = null;
> > SqlConnection cn = new SqlConnection(); // with necessary

parameters
> > cn.Open();
> > using (SqlCommand cm = new SqlCommand()) // with necessary

> parameters
> > {
> > // Set up command object
> > dr = cm.ExecuteReader(CommandBehavior.CloseConnection);
> > }
> > return dr;
> > }
> > }
> >
> >

>
>



 
Reply With Quote
 
Chris Taylor
Guest
Posts: n/a
 
      24th Jun 2004
Hi,

No, my description describes the sequence of events starting in the static
function. If you notice that when I reach the point in the description where
the using block ends I state the following:

"the DataReader is disposed at the end of the using statement, the
Connection is closed and the reference to the
Command is set to null. At this point neither the Command object nor the
Connection object are reacheable and are elligeable for collection"


Hope this helps

--
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor


"Daniel Billingsley" <dbillingsley@NO_durcon_SPAAMM.com> wrote in message
news:e7G$(E-Mail Removed)...
> Do I understand you to be suggesting that the command is not really

disposed
> by the using{} in the static factory: "the connection is still reacheable
> via the reference to the Command object which is held by the DataReader"
>
> Not only would I find that odd that the compiler decides the using{} will
> not really work the way I expect, but also doesn't seem consistent with

the
> fact that if I put a using{} around the connection in the static factory I
> get an error in the BO saying I can't use the DataReader on a closed
> connection.
>
> I guess my original question might be rephrased to ask if this would be
> considered acceptable since I don't explicitly dispose the connection and
> rely on the CloseConnection behavior to do so indirectly.
>
> "Chris Taylor" <(E-Mail Removed)> wrote in message
> news:%(E-Mail Removed)...
> > Hi Daniel,
> >
> > Yes, the connection is closed when the Dispose/Close method is called on

> the
> > DataReader. I have taken the libety of including a summary description

of
> > the key point that occur in the code.
> >
> > The SqlConnection is allocated on the managed heap, so regardless of if

it
> > was allocated by a call to a static or non-static method the object

exists
> > on the heap and as long as it is reacheable it will not be elligeable

for
> > collection. Since you are returning the DataReader from the

GetDataReader
> > method, the connection is still reacheable via the reference to the

> Command
> > object which is held by the DataReader. In the case of
> > CommandBehaviour.CloseConnection when the DataReader is disposed at the

> end
> > of the using statement, the Connection is closed and the reference to

the
> > Command is set to null. At this point neither the Command object nor the
> > Connection object are reacheable and are elligeable for collection. Of
> > cource since you are no longer referencing the DataReader it is also
> > elligeable for collection, however even if you mantained the reference

to
> > the DataReader, the Command and Connection object are no longer

reacheable
> > since the only surviving reference was that in the DataReader and that

has
> > been set to null.
> >
> > The best way to verify these things is to use ILDASM and take a look at

> what
> > the code is doing internally.
> >
> > Hope this helps
> >
> > --
> > Chris Taylor
> > http://dotnetjunkies.com/weblog/chris.taylor
> >
> >
> > "Daniel Billingsley" <dbillingsley@NO_durcon_SPAAMM.com> wrote in

message
> > news:(E-Mail Removed)...
> > > Given that
> > > - The CloseConnection CommandBehavior of ExecuteReader causes the

> > connection
> > > to be "closed" when the DataReader is closed
> > > - Close and Dispose are interchangeable on these ADO objects
> > >
> > > 1) Will the connection object in the following code get

closed/disposed?
> > >
> > > 2) Since it's created in the static method of the DataFactory class

but
> > > referenced by the DataReader in the BusinessObject class, how would

you
> > > describe the scope of the connection object?
> > >
> > > Wait - variables have scope, not objects in memory, right? So it will

> be
> > > referenced both by the DataReader in the BusinessObject and the

variable
> > cn
> > > within the scope of the GetDataReader method, right? We know when the

> cn
> > > reference goes away, of course... so when the DataReader is closed

then
> > the
> > > connection will also be closed and all will be right in the GC world.
> > > Yes???
> > >
> > > If possible, can you enlighten me on how you'd go about testing such

a
> > > thing, if it's possible. The DataReader doesn't expose any

information
> > > about the connection so it can't be checked through the back door that

> > way.
> > >
> > > ============
> > >
> > > class BusinessObject
> > > {
> > > public ReadData
> > > {
> > > using (SqlDataReader dr = DataFactory.GetDataReader()) // has

some
> > > parameters in reality
> > > {
> > > // extract the data from the datareader here
> > > }
> > > }
> > > }
> > >
> > > class DataFactory
> > > {
> > > public static SqlDataReader GetDataReader() // takes some

parameters
> in
> > > reality
> > > {
> > > SqlDataReader dr = null;
> > > SqlConnection cn = new SqlConnection(); // with necessary

> parameters
> > > cn.Open();
> > > using (SqlCommand cm = new SqlCommand()) // with necessary

> > parameters
> > > {
> > > // Set up command object
> > > dr = cm.ExecuteReader(CommandBehavior.CloseConnection);
> > > }
> > > return dr;
> > > }
> > > }
> > >
> > >

> >
> >

>
>



 
Reply With Quote
 
Daniel Billingsley
Guest
Posts: n/a
 
      25th Jun 2004
That doesn't really answer my question.

The "reference to the Command" that is set to null when the DataReader is
disposed would be referring to a Command that has already been disposed (in
the static function) though, right?


 
Reply With Quote
 
Chris Taylor
Guest
Posts: n/a
 
      25th Jun 2004
That is correct, however calling the dispose method does not make an object
unreacheable so only once the command object is set to null does the memory
allocated for the command object become elegiable for collection. So even
though the command object has been disposed, the managed memory which was
allocated for the object lingers until the DataReader releases its
reference.

--
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor


"Daniel Billingsley" <dbillingsley@NO_durcon_SPAAMM.com> wrote in message
news:(E-Mail Removed)...
> That doesn't really answer my question.
>
> The "reference to the Command" that is set to null when the DataReader is
> disposed would be referring to a Command that has already been disposed

(in
> the static function) though, right?
>
>



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
If my System.IO.StreamWriter Write method throws "The specified network name is no longer available." and I try to Dispose or Close it in the finaly clause the close or dispose method just throws "The specified network name is no longe Daniel Microsoft C# .NET 1 8th Sep 2005 09:44 AM
If my System.IO.StreamWriter Write method throws "The specified network name is no longer available." and I try to Dispose or Close it in the finaly clause the close or dispose method just throws "The specified network name is no longe Daniel Microsoft Dot NET 3 8th Sep 2005 07:54 AM
If my System.IO.StreamWriter Write method throws "The specified network name is no longer available." and I try to Dispose or Close it in the finaly clause the close or dispose method just throws "The specified network name is no longe Daniel Microsoft Dot NET Framework 1 8th Sep 2005 04:11 AM
Dispose vs Close Robert Strickland Microsoft ADO .NET 5 12th Nov 2004 06:30 PM
Close & Dispose Tim Bücker Microsoft C# .NET 2 11th Dec 2003 11:18 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 06:29 PM.