Connection pooling...

B

bill yeager

I'm using connection pooling (0 min/100 max) in an asp.net
web application. All users log in using the same
connectionstring.

Is it prudent, for instance, to close and dispose of my
connection after a database update takes place which I
normally do when I'm not using connection pooling?
 
W

William \(Bill\) Vaughn

With ASP applications, it's generally prudent to close connections--disposal
is not necessary.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
 
M

Miha Markic [MVP C#]

Hi Bill,

William (Bill) Vaughn said:
With ASP applications, it's generally prudent to close
connections--disposal is not necessary.

Assuming the assumed behaviour from connection class :)
IOW it is up to connection class implementation what it really does upon
Close or Dispose.
 
A

Angel Saenz-Badillos[MS]

Very good point Miha, for the 2.0 release we almost changed the default
behavior of SqlCommand.Dispose to clean up some expensive resources for a
new feature we were planning to add. The feature got cut and SqlCommand
Dispose continues to do exactly what it did in v1.1 (not much), but I really
hate to see any advice that discourages using the Dispose method of
IDisposable objects.

Of course Bill knows what he is talking about and is perfectly right, in the
current implementation of the ado.net code it is not necesary to call
sqlconnnection.Dispose if you have already closed the connection. In fact
the end result may even save a few cycles in the short run and I have seen
very solid developers who fully understand the situation decide to not use
Dispose.

What happens if in a _future_ implementation we add something to the
SqlConnection Dispose method that makes it different from close? We fully
expect people to call Dispose in IDisposable objects, preferably with the
"using" construct or in a finally block.

--
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.
I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/
 
W

WJ

Miha Markic said:
Hi Bill,



Assuming the assumed behaviour from connection class :)
IOW it is up to connection class implementation what it really does upon
Close or Dispose.

I understand what you are saying, but I would use the "close" method instead
of "dispose" because the original poster asked for "connection pooling"

My thinking is: "dispose" signals the GC to get rid of it as soon it is
disposed of, as a result, the next user will have to "new" it again, then
connection pooling is of no use here. While "close" just lets it hybernates
until someone calls it again ?

John
 
S

Sahil Malik

Nice to see you back in action !!!

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik


Angel Saenz-Badillos said:
Very good point Miha, for the 2.0 release we almost changed the default
behavior of SqlCommand.Dispose to clean up some expensive resources for a
new feature we were planning to add. The feature got cut and SqlCommand
Dispose continues to do exactly what it did in v1.1 (not much), but I
really
hate to see any advice that discourages using the Dispose method of
IDisposable objects.

Of course Bill knows what he is talking about and is perfectly right, in
the
current implementation of the ado.net code it is not necesary to call
sqlconnnection.Dispose if you have already closed the connection. In fact
the end result may even save a few cycles in the short run and I have seen
very solid developers who fully understand the situation decide to not use
Dispose.

What happens if in a _future_ implementation we add something to the
SqlConnection Dispose method that makes it different from close? We fully
expect people to call Dispose in IDisposable objects, preferably with the
"using" construct or in a finally block.

--
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.
I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/




Miha Markic said:
Hi Bill,



Assuming the assumed behaviour from connection class :)
IOW it is up to connection class implementation what it really does upon
Close or Dispose.
 
S

Sahil Malik

I am gonna risk posting this here so the super intelligent folks on this
newsgroup can fix my understanding of the picture. :) .. I don't mind
making myself look like a complete idiot if I learn something good out of
this.

So here's my understanding ----

Think of it this way, you are writing a class that holds a bunch of
expensive objects.
Lets say your class is "C" and the expensive objects it holds are A and B

Now you know that your objects are expensive, and being the prudent
developer you are, you decide to implement IDisposable, which means add a
method called "Dispose".

Now in your code say in function function "f" calls function "F" you do
this.
f{
F() ;
// Point #Y
}

F
{
... working with C
C.Dispose
{{
// Calling C.Dispose ended up calling ...
A.Dispose() ;
B = null ;
}}
/// Point #X
}

For argument's sake lets assume that A was a managed object that implemented
Dispose, and B was say an instance of a COM object. ... then ...
At Point #X - A and B will be GC-reusable, because A fell out of scope and B
was explicitly set to null, but C will not be.
But at Point #Y - C will be GC-reusable.

In other words, Dispose is just as special as your implementer implemented
it. And yes by convention if a class implements it, you should call it.

In that sense, calling dispose on a Connection object, does NOT Guarantee
reuse of GC memory by the object itself, but it does guarantee GC reuse of
the expensive objects it might hold, and the ConnectionPooling Mechanism in
ADO.NET underneath ensures that a closed connection (closed by say
SqlConnection.Close()) is happily reusable. So when Connection.Dispose calls
Connection.Close, the exact pointer reference of the connection object still
stays unusable (which is no big deal) until the connection object falls out
of scope or is explicitly set to null, but the underlying Connection to the
database is pooled.

And as far as GC goes, it calls Finalize, which calls it in a hurry during
GC and might not do as good a cleanup job as your code might ask it to do in
Finalize. Plus in Dispose you should have called SuppressFinalize anyway. I
usually call a Debug.Print also, to catch wherever in my code someone forgot
to call a dispose where he shud've.

Am I right or am I high on Advil? (WHEEZE COUGH COUGH !!)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
W

William \(Bill\) Vaughn

The problem is, the GC does not run immediately (as it did in COM). It runs
when it discovers there is a lack of RAM. This can mean an object is not
disposed (closed?) for some time post "dispose".

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
 
M

Miha Markic [MVP C#]

Hi Sahil,

Sahil Malik said:
I am gonna risk posting this here so the super intelligent folks on this
newsgroup can fix my understanding of the picture. :) .. I don't mind
making myself look like a complete idiot if I learn something good out of
this.

So here's my understanding ----

Think of it this way, you are writing a class that holds a bunch of
expensive objects.
Lets say your class is "C" and the expensive objects it holds are A and B

Now you know that your objects are expensive, and being the prudent
developer you are, you decide to implement IDisposable, which means add a
method called "Dispose".

Now in your code say in function function "f" calls function "F" you do
this.
f{
F() ;
// Point #Y
}

F
{
... working with C
C.Dispose
{{
// Calling C.Dispose ended up calling ...
A.Dispose() ;
B = null ;
}}
/// Point #X
}

For argument's sake lets assume that A was a managed object that
implemented Dispose, and B was say an instance of a COM object. ... then
...
At Point #X - A and B will be GC-reusable, because A fell out of scope and
B was explicitly set to null, but C will not be.
But at Point #Y - C will be GC-reusable.

In other words, Dispose is just as special as your implementer implemented
it. And yes by convention if a class implements it, you should call it.

In that sense, calling dispose on a Connection object, does NOT Guarantee
reuse of GC memory by the object itself, but it does guarantee GC reuse of
the expensive objects it might hold, and the ConnectionPooling Mechanism
in ADO.NET underneath ensures that a closed connection (closed by say
SqlConnection.Close()) is happily reusable. So when Connection.Dispose
calls Connection.Close, the exact pointer reference of the connection
object still stays unusable (which is no big deal) until the connection
object falls out of scope or is explicitly set to null, but the underlying
Connection to the database is pooled.

And as far as GC goes, it calls Finalize, which calls it in a hurry during
GC and might not do as good a cleanup job as your code might ask it to do
in Finalize. Plus in Dispose you should have called SuppressFinalize
anyway. I usually call a Debug.Print also, to catch wherever in my code
someone forgot to call a dispose where he shud've.

Am I right or am I high on Advil? (WHEEZE COUGH COUGH !!)

I guess you are mostly right, except for finalizer where I would like to add
that you really shouldn't implement one unless you are dealing with
unmanaged code (or debugging).
If you don't have one, the call to SuppressFinalize is redundant because GC
will never invoke finalizer as there doesn't exist one (if you haven't
created it).
Thus, never ever create a finalizer unless you are dealing with unmanaged
code. And if you create one, you really have to be extremly careful in its
implementation.
 
S

Sahil Malik

Fantastic Miha, and thank you for your reply.

Regards the conventional logic of not implementing finalizer if you've done
dispose, I kinda disagree with that, but you are right, .. what you say is
what 95% of the folks out there would insist/swear upon.

My thoughts about that have been that, if I see a debug.assert("Finalizer
not called") within my IDE while I am running my program thru visual studio,
that helps me catch situations where I should have called Dispose, but I did
not. I had blogged about it way back when I was a young kid.
http://dotnetjunkies.com/WebLog/sahilmalik/archive/2004/05/19/14019.aspx

Anyway, that's an arguable thing :p .. 3:03 AM .. I need some sleep .. hehe
:)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
M

Miha Markic [MVP C#]

Hi Sahil,

Sahil Malik said:
Fantastic Miha, and thank you for your reply.

Regards the conventional logic of not implementing finalizer if you've
done dispose, I kinda disagree with that, but you are right, .. what you
say is what 95% of the folks out there would insist/swear upon.

My thoughts about that have been that, if I see a debug.assert("Finalizer
not called") within my IDE while I am running my program thru visual
studio, that helps me catch situations where I should have called Dispose,
but I did not. I had blogged about it way back when I was a young kid.
http://dotnetjunkies.com/WebLog/sahilmalik/archive/2004/05/19/14019.aspx

Yes, I've mentioned the "debugging" in my post.
You might consider putting all finalizer related code in #if DEBUG #endif
block then.
Anyway, that's an arguable thing :p .. 3:03 AM .. I need some sleep ..
hehe :)

Just don't dream of finalizers :)
 
C

Cor Ligthert

Angel,

The same as Sahil, good to see you back and sad that what I saw as "your
point" is cut.

However now I become not to understand it anymore.

Because the fact that something inherits whatever member from a parent
class, does not mean for me not that all those members should be used.

The connection inherits from component which implements iComponent which
inherits IDisposable.

From you I did understand, that in the connection "Dispose" was overloaded
and was acting too the connectionpooling.

Now because of what you write I become curious about this, if this is true.
Starting dispose only for cleaning up has no sence or the connection should
be a hugh resource as a bitmap or whatever.

Public sub myroutine(dataset)
dim conn as new xxxconnection
dim da as new dataadapter(x,conn)
da.fill(dataset)
end sub

In my opinion will the GC clean it up anyhow because it lost its own
reference when it goes out of scope an there is not any reference set too
it. (While the close is done by the dataadapter in this not so nice written
situation, I normally close it in finally however use because you said it
now dispose)

And therefore maybe you can clear this up for me.

Cor
 
A

Angel Saenz-Badillos[MS]

Sorry Cor, did not mean to confuse the issue, I brought in the SqlCommand
object into a SqlConnection discussion.

I used the SqlCommand as an example of an IDisposable object that currently
does not have an implementation for Dispose. When you call SqlCommand
Dispose you will actually be calling Component Dispose, because of this most
people do not bother to call SqlCommand.Dispose. In ado.net 2.0 we almost
started releasing important resources in the SqlCommand Dispose object which
would have made it necesary for people to start calling it.

We are currently releasing very important resources in Dispose _or_ in the
Close method for the SqlConnection, in the current implementation it does
not matter whether you call one or the other (or both) but you MUST call one
of them. Calling both (as I advocate) is clearly the most expensive, but IMO
well worth the cost.

--
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.
I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/
 
C

Cor Ligthert

Angel,

I see it, I saw connection because I was happy you was back and used that
your major interest is the connection while you wrote command instead of
connection.

Sorry from my side as well.

:)

Cor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top