How can I make sure all unmanaged resources had been released ?

  • Thread starter Thread starter Eric
  • Start date Start date
E

Eric

for example: SqlConnection is used in my project, how can I know if all
connections were closed after open and execution. If some guys forget to
close connections after using, how can i check it out ?


best,
eric
 
Eric,

The System.Data.SqlClient library is a pure .Net client interface to the
database. Therefore if the connection is not closed, there is the timeout
and garbage collector to sort it out if someone doesn't do the job of
closing it down manually.

What type of unmanaged resources are you refering too?

If the managed code is hooked into native code via the Interop's, then the
garbage collector will again call the destructors on your unmanaged code
when it thinks you're finished with them during a clear up.

Therefore if the unmanaged code is not desroying its objects, the garbage
collector destroy these uncleared objects either as the onus lies with the
unmanaged resource and not the .Net application.
 
Thank you for your reply.

SqlClient.SqlConnection should manually call Close() or Dispose() after
using. MSDN point out this. If we didn't call Close() or Dispose() manually,
SqlConnecont won't be closed when the connection object is out of range, GC
would close the connection object in some magic time. That means, if we
don't call Close() or Dispose() as soon as possible, the connection_pool
would be exhausted.

What's the worse, the connection_pool is organized by *process* and
*ConnectionString*. This means diffrent modules in one program, would share
a same connection_pool. If one connection_pool was exhausted, we can not
even find out which module cause this problem. In a huge project, this will
be a very troublesome problem, I think.
 
Firstly, I'm not sure why this is a problem... The pooling technique is
offered as a default so that the overhead is kept down when two connections
"appear" to be the same in the same process. This saves memory and resources
in general. If the connection times out because the "Connection Lifttime"
has expired, the the GC removes the pool from memory...

It's not a case of should, you "must" call Close()/Dispose()... Although
it's not as imperative as, calling "Open()" say, the fact is, failing to
call close leaves this connection wide open, and if you've numerous
different open connections, this in itself saps system resources.

Surely a simply find in the solution on "Open()" will give you an immediate
listing of all the instances where a connection is established?

Finally, you can turn pooling off by passing in "Pooling=false" in the
connection string. This would mean every new connection that is created is
set up as a seperate connection, regardless if one (or hundred) just like it
have already been used.

http://msdn.microsoft.com/library/d...nectionpoolingforsqlservernetdataprovider.asp

If you employ proper connection maintenance from the start, it won't be a
problem...
 
Let's have a test to find out what would happen, if we don't manually call
Dispose() or such like that :


using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace PureTest
{
public class Class1
{
public Class1()
{
}

[STAThread]
static void Main()
{
while(true)
{
int i = 0;
try
{
for(i = 0; i < 1000; i++)
{
SqlConnection con = new
SqlConnection("server=ERIC;uid=eric;pwd=eric;database=settlement");
con.Open();
}
}
catch(Exception ee)
{
MessageBox.Show("count=" + i.ToString() + "\r\n");

if(MessageBox.Show(ee.Message + "\r\n\r\ncontinue?", "connect fail",
MessageBoxButtons.YesNo) == DialogResult.No)
{
break;
}

}
}
}
}
}


We will see that connection_pool keep exhausted. This sample looks stupid,
but similar situation can really happen in a complex project.

Not_using connection pool, I don't think this is a good idea. Connecting is
an expensive operation, and Real_Connection to SQLServer is also limited.



best,
eric
 
Eric,

Like I said, it's not right if you don't call close, I don't really see what
other option you have on a large scale project. If you have the source, then
a simply match on Open/Close calls will do.



Eric said:
Let's have a test to find out what would happen, if we don't manually call
Dispose() or such like that :


using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace PureTest
{
public class Class1
{
public Class1()
{
}

[STAThread]
static void Main()
{
while(true)
{
int i = 0;
try
{
for(i = 0; i < 1000; i++)
{
SqlConnection con = new
SqlConnection("server=ERIC;uid=eric;pwd=eric;database=settlement");
con.Open();
}
}
catch(Exception ee)
{
MessageBox.Show("count=" + i.ToString() + "\r\n");

if(MessageBox.Show(ee.Message + "\r\n\r\ncontinue?", "connect fail",
MessageBoxButtons.YesNo) == DialogResult.No)
{
break;
}

}
}
}
}
}


We will see that connection_pool keep exhausted. This sample looks stupid,
but similar situation can really happen in a complex project.

Not_using connection pool, I don't think this is a good idea. Connecting
is
an expensive operation, and Real_Connection to SQLServer is also limited.



best,
eric




Dan =o) said:
Firstly, I'm not sure why this is a problem... The pooling technique is
offered as a default so that the overhead is kept down when two connections
"appear" to be the same in the same process. This saves memory and resources
in general. If the connection times out because the "Connection Lifttime"
has expired, the the GC removes the pool from memory...

It's not a case of should, you "must" call Close()/Dispose()... Although
it's not as imperative as, calling "Open()" say, the fact is, failing to
call close leaves this connection wide open, and if you've numerous
different open connections, this in itself saps system resources.

Surely a simply find in the solution on "Open()" will give you an immediate
listing of all the instances where a connection is established?

Finally, you can turn pooling off by passing in "Pooling=false" in the
connection string. This would mean every new connection that is created
is
set up as a seperate connection, regardless if one (or hundred) just like it
have already been used.

http://msdn.microsoft.com/library/d...nectionpoolingforsqlservernetdataprovider.asp

If you employ proper connection maintenance from the start, it won't be a
problem...


Eric said:
Thank you for your reply.

SqlClient.SqlConnection should manually call Close() or Dispose() after
using. MSDN point out this. If we didn't call Close() or Dispose()
manually,
SqlConnecont won't be closed when the connection object is out of
range,
GC
would close the connection object in some magic time. That means, if we
don't call Close() or Dispose() as soon as possible, the
connection_pool
would be exhausted.

What's the worse, the connection_pool is organized by *process* and
*ConnectionString*. This means diffrent modules in one program, would
share
a same connection_pool. If one connection_pool was exhausted, we can
not
even find out which module cause this problem. In a huge project, this
will
be a very troublesome problem, I think.




"Dan =o)" <danielbass [at] postmaster [dot] co [dot] uk> дÈëÓʼþ
Eric,

The System.Data.SqlClient library is a pure .Net client interface to the
database. Therefore if the connection is not closed, there is the timeout
and garbage collector to sort it out if someone doesn't do the job of
closing it down manually.

What type of unmanaged resources are you refering too?

If the managed code is hooked into native code via the Interop's, then
the
garbage collector will again call the destructors on your unmanaged code
when it thinks you're finished with them during a clear up.

Therefore if the unmanaged code is not desroying its objects, the garbage
collector destroy these uncleared objects either as the onus lies with
the
unmanaged resource and not the .Net application.


for example: SqlConnection is used in my project, how can I know if all
connections were closed after open and execution. If some guys
forget
to
close connections after using, how can i check it out ?


best,
eric
 
Dan,

Your comments is helpful, but I have some diffrent viewpoints.

A simply match on Open/Close won't be enough for Resource Safe in dotNET, as
that a simply match on new/delete is not enough for Memory Safe in C++.

To my opinion, Resource Safe is also very important for a business system.
Without Resource Safe, you are unable to say when the system will break
down. Yes, GC maybe help in some situation, but the system may have broken
down before GC.Collect().

So, we have to exactly manually open and free every system resource,
obviating the disturbance of Exceptions. I feel it's even more boring than
keep Memory Safe in C++.

Sorry for the rant.

best,
eric



Dan =o) said:
Eric,

Like I said, it's not right if you don't call close, I don't really see what
other option you have on a large scale project. If you have the source, then
a simply match on Open/Close calls will do.



Eric said:
Let's have a test to find out what would happen, if we don't manually call
Dispose() or such like that :


using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace PureTest
{
public class Class1
{
public Class1()
{
}

[STAThread]
static void Main()
{
while(true)
{
int i = 0;
try
{
for(i = 0; i < 1000; i++)
{
SqlConnection con = new
SqlConnection("server=ERIC;uid=eric;pwd=eric;database=settlement");
con.Open();
}
}
catch(Exception ee)
{
MessageBox.Show("count=" + i.ToString() + "\r\n");

if(MessageBox.Show(ee.Message + "\r\n\r\ncontinue?", "connect fail",
MessageBoxButtons.YesNo) == DialogResult.No)
{
break;
}

}
}
}
}
}


We will see that connection_pool keep exhausted. This sample looks stupid,
but similar situation can really happen in a complex project.

Not_using connection pool, I don't think this is a good idea. Connecting
is
an expensive operation, and Real_Connection to SQLServer is also limited.



best,
eric




Dan =o) said:
Firstly, I'm not sure why this is a problem... The pooling technique is
offered as a default so that the overhead is kept down when two connections
"appear" to be the same in the same process. This saves memory and resources
in general. If the connection times out because the "Connection Lifttime"
has expired, the the GC removes the pool from memory...

It's not a case of should, you "must" call Close()/Dispose()... Although
it's not as imperative as, calling "Open()" say, the fact is, failing to
call close leaves this connection wide open, and if you've numerous
different open connections, this in itself saps system resources.

Surely a simply find in the solution on "Open()" will give you an immediate
listing of all the instances where a connection is established?

Finally, you can turn pooling off by passing in "Pooling=false" in the
connection string. This would mean every new connection that is created
is
set up as a seperate connection, regardless if one (or hundred) just
like
it
have already been used.
http://msdn.microsoft.com/library/d...nectionpoolingforsqlservernetdataprovider.asp
If you employ proper connection maintenance from the start, it won't be a
problem...


Thank you for your reply.

SqlClient.SqlConnection should manually call Close() or Dispose() after
using. MSDN point out this. If we didn't call Close() or Dispose()
manually,
SqlConnecont won't be closed when the connection object is out of
range,
GC
would close the connection object in some magic time. That means, if we
don't call Close() or Dispose() as soon as possible, the
connection_pool
would be exhausted.

What's the worse, the connection_pool is organized by *process* and
*ConnectionString*. This means diffrent modules in one program, would
share
a same connection_pool. If one connection_pool was exhausted, we can
not
even find out which module cause this problem. In a huge project, this
will
be a very troublesome problem, I think.




"Dan =o)" <danielbass [at] postmaster [dot] co [dot] uk> дÈëÓʼþ
Eric,

The System.Data.SqlClient library is a pure .Net client interface to the
database. Therefore if the connection is not closed, there is the timeout
and garbage collector to sort it out if someone doesn't do the job of
closing it down manually.

What type of unmanaged resources are you refering too?

If the managed code is hooked into native code via the Interop's, then
the
garbage collector will again call the destructors on your unmanaged code
when it thinks you're finished with them during a clear up.

Therefore if the unmanaged code is not desroying its objects, the garbage
collector destroy these uncleared objects either as the onus lies with
the
unmanaged resource and not the .Net application.


for example: SqlConnection is used in my project, how can I know
if
all
connections were closed after open and execution. If some guys
forget
to
close connections after using, how can i check it out ?


best,
eric
 
Back
Top