If you have a C# function with Sqlaccess, is it mandatory to close all objects/handles, or is everything cleaned up automatically once you exit the function
For example:
void DoSqlStuff()
{
SqlConnection sqlConn = new SqlConnection(...);
SqlCommand cmd = new SqlCommand(...);
SqlDataReader sqlData= null;
sqlConn,Open();
sqlData = cmd.ExecutReader();
while(sqlData.Read())
{
...
}
}
Is it optional, recommended or mandatory to close SqlConn and SqlData?
Thanks.
You should close the SqlConnection object as soon as you're done with it. If you don't then the connection will remain open, and will not be available to handle other requests.
The using statement is useful for this. It will call Dispose() on the object for you:
using (SqlConnection cn = new SqlConnection(connectionString))
{
SqlCommand cm = new SqlCommand(commandString, cn)
cn.Open();
cm.ExecuteNonQuery();
}
You don't need to have a separate using statement for the SqlDataReader (as well as one using statement for the connection) unless you plan do perform other operations with the connection after the SqlDataReader has fully read through the row set.
If you are just opening a connection, reading some data using the reader, and then closing the connection, then one using statement for the entire block of code (surrounding the connection) will suffice as the garbage collector will clean up all resources tied to the connection that is disposed by the first using statement.
Anyway, here's a good article that describes it all...
You should close everything before returning from the function. Open datareaders mean open cursors on the database, resulting in increased memory usage. Same goes for database connections.
Unused objects are not immediately freed in C#, but only when garbage collection is performed, which is not deterministic.
All three classes have a Dispose() method. Mandatory is too strong, but definitely highly recommended you use the using keyword so Dispose() is automatically called. Failing to do so makes your program run "heavy", using more system resources than necessary. And outright failure when you don't use the "new" keyword enough to trigger the garbage collector.
Calling Close on the SQL connection won't actually close it, but will return it to a connection pool to be reused, improving performance.
Additionally it is generally poor practice to not explicitly dispose of unmanaged resources when you are finished with them (asap).
Be careful with absolutes here. A lot depends on what you are doing & where the inefficiencies may lie.
In a Web Page where each user has a separate security context you may have no choice but to establish a new SQL connection with new security credentials with each page hit. Clearly nicer if you can use a pool of SQL connections with a shared security context & let the Web page filter the results but perhaps you can't.
In early versions of SQL Server ie (v6.5 or less) the Login Authentication was done by SQL Server. Also SQL was severely constrained by connection memory & the number of active connections it could handle. So it was a great idea to drop your connection when not in use.
Post v6.5, most people use Windows Authentication to login to SQL. This causes a lot of network calls between servers & some latency. Kerberos Security is even more chatty, Thus establishing a SQL connection is expensive. For that reason you need to find a balance between Holding a connection open for the life of your WinForms application vs Opening & closing it within each method call.
As a rough guide, if you think your app is going to want to talk to SQL in the next, say 30 secs. Keep the established connection open. If they've minimised your app, not touched it within a timeout period, or you've got all the data in RAM & they are unlikely to need anything more from the SQL system. Close the connection.
Consider creating a Class with a System Timer to hold the connection. Your class will always provide a valid connection, but perhaps the class will choose to drop it & free the connection load on SQL when appropriate.
Unless you are also writing Server based code, a small amount of memory inefficiency might not even be noticed. But 2-10,000 clients all poorly using your Security & Data Servers is likely to bring your Data Centre to its knees.
Explicit disposing in the finally statement is another approach, although the using statement is a much better solution. It produces a bit more code, but demonstrates the goal...
SqlConnection conn = null;
try
{
//create connection
SqlCommand cmd = null;
try
{
//create command
SqlDataReader reader = null;
try
{
//create reader
}
finally
{
reader.Dispose();
}
}
finally
{
cmd.Dispose();
}
}
finally
{
conn.Dispose();
}
Any class handling SQL stuff like Connections should implement the IDisposable interface as stated by Microsoft .NET coding guidelines.
Thus, you should probably close and dispose your connection in your Dispose method.
Related
It might be my misunderstanding but I do have big problem. Please consider the following code:
static void Main(string[] args)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
int i = 10;
con.Close();
con.Dispose();
}
int y = 10;
}
At line int y = 10, place a break point.
Now, go to your SQL Server and right click on SQl Connection which is the same connection as connectionString in above code, and choose "Activity Monitor". Run the above code and check the SQL Server Activity monitor. When con.Open() is executed, the activity monitor shows that the connection has been made. So far, so good! But when the cursor hits the line which indicates int y = 10;, the Activity Monitor still shows you the connection which should not be there! Because I closed it, I disposed it and even I passed the using statement as well.
Does anyone know how I can close the connection?
This is the connection pool, correctly doing its job. This is a good thing, in virtually all circumstances. If you don't want this: disable the connection pool via the connection string.
Basically, you need to keep separate 2 concepts:
the SqlConnection managed connection instance
the underlying unmanaged connection object
In normal usage, closing or disposing the managed connection just puts the unmanaged connection back in the pool, ready for quick use. If you want the managed and unmanaged connection to die together, you must disable connection pooling.
Database connections in .NET are pooled by default. That means that although a single instance of a connection (SqlConnection) is closed, the framework will actually keep the underlying real connection to allow new connections to be created faster. Unless you have good reasons, you probably don’t want to mess around with this, as it does give you a good performance boost.
That being said, you actually can force the pool to close all its connection it still has. You can do that with SqlConnection.ClearPool, or—by using a even bigger hammer—with SqlConnection.ClearAllPools. With that, the real connections are closed as well, and your activity monitor won’t show the connections any more.
I'm writing a program that generates Sitemaps. To avoid duplicates I'm using MSSQL Server to store links that are found. during this process It may read and write millions of links and the process of reading and writing may have very little gaps between them (I mean the time between each access to database is very tiny).
I want to know If I can open the connection when the program starts and close it at the end. please consider that creating some sitemaps may take days to finish. Or is it wise to open and close connection each time I want to access the db?
By the way, I'm using sql server locally.
The answer to your question is the Connection Pooling feature.
It is always preferable to open the connection just when needed, access your data, close and dispose the connection immediately
Indeed a specific work pattern exists
using(SqlConnection con = new SqlConnection(.....))
{
... do your work with the database here ....
}
The using statement ensures that the object created at the opening is closed and disposed at the closing braces. Even if an Exception occurs in database code.
This doesn't mean that you cannot try to optimize your code. For example you could gather a few of sitemaps together and write them in just one shot, but usually it is best to follow a simple work pattern, finish the work as soon as possible and worry for optimization later.
You can work with the following code :
SqlConnection conn;
try
{
conn = new SqlConnection(_dbconnstr));
}
catch
{
//exceptions are bubbled
throw;
}
finally
{
//Dispose is always called
conn.Dispose();
}
hope this helps!
I usually open and close connection each time I use it.
Releasing resources must be done when there is many connections around.
If you are the only one, you might keep your resources.
Be aware of setting timeout connection.
Good luck guy!
It is better to open/close the connection. There is no benefits in kipping connection open. ADO.NET Connection pooling (which is on by default) will take care of which connection to close and when.
From MSDN
CAUTION It is recommended that you always close the Connection when
you are finished using it in order for the connection to be returned
to the pool. This can be done using either the Close or Dispose
methods of the Connection object. Connections that are not explicitly
closed might not be added or returned to the pool. For example, a
connection that has gone out of scope but that has not been explicitly
closed will only be returned to the connection pool if the maximum
pool size has been reached and the connection is still valid.
If you know it's going to take a while, what about writing to a local data table and then when you reach a threshold, write all the records to the database.
Or even write the info to a local file (format of your choice) and then write that file to the database in one shot (or multiple shots if you want to do it every x records or y minutes.)
I've got a sql server 2k8 database that's being populated with several hundred thousand records per day.
I'm currently writing some code that's going to make a call to the db, retrieve n records, process them, and write some data back to the db.
There are two ways I see to do this (psuedo code):
function xyz() {
conn = conn creation code
conn.open();
while(not last record) {
select next 1000 records
process each record
last record = true
}
conn.close();
xyz();
}
Essentially creating one connection per batch. The second method:
function xyz() {
conn = connection creation code
while(conn.open();) {
select next 1000 records
process each record
last record = true
}
conn.close();
xyz();
}
I'm curious what's better practice. I feel like it's the latter, but it's also going to have a more-or-less permanent/persistent connection to my db. I'm worried about possible memory overruns or some such.
Thoughts?
Scott
ADO.Net Sqlclient provider (which is I assume you will use, since you say is C#) automatically does connection pooling, see SQL Server Connection Pooling (ADO.NET). Pooled connection are not truly closed when you call Close, they are simply returned to the pool. 'Opening' and 'closing' pooled connection is very fast.
unrelated note: you should embed your connection in a using block:
using (SqlConnection conn = new SqlConnection(...))
{
conn.Open ();
...
}
This way you avoid leaking connecitons in exception conditions.
I would handle the connection outside of the function and pass it in. The function is designed to process entries, not to connect to the database and process entries. I would separate those two jobs.
As far as connection opening/closing goes: yes, you should avoid it. It's not too terribly slow on it's own, but if you're just doing processing, there's no reasons to open/close the connection over and over again. If it's due to memory usage (I'm not very familiar with C# by the way, so this part might just be wrong), you should be freeing the result sets. Closing the connection will free the memory associated with it, however, you should be able to get the same effect without having to reconnect.
It depends on what "process each record" means. If that takes a notable amount of time and does not need to maintain the connection, you might want to reconsider keeping the connection open and let the pool handle it.
But if it is constantly reading from/to the connection, you should not artificially disconnect/reconnect.
There is no reason to keep closing and re-opening the connection. It imposes needless load on the database and the network.
If connecting to a database consumes a lot of resources, why should a database connection always be closed in your application if you have to open it again? Can I just make this connection available globally throughout my application so that other classes and methods can reuse it?
For example (in pseudo code):
public class PopulateGridViews()
{
public SqlConnection conn = new SqlConnection(#"Database:DATABASE");
conn.Open();
void PopulateGrid1()
{
SqlCommand cmd = new SqlCommand("SELECT * FROM TABLE1");
cmd.Connection = conn;
cmd.ExecuteNonQuery();
cmd.Dispose();
// Populate Grid1
}
void PopulateGrid2()
{
SqlCommand cmd = new SqlCommand("SELECT * FROM TABLE2");
cmd.Connection = conn;
cmd.ExecuteNonQuery();
cmd.Dispose();
// Populate Grid2
}
}
You should not leave connections open.
You should:
Open connections as late as possible
Close connections as soon as possible
The connection itself is returned to the connection pool. Connections are a limited and relatively expensive resource. Any new connection you establish that has exactly the same connection string will be able to reuse the connection from the pool.
We strongly recommend that you always
close the connection when you are
finished using it so that the
connection will be returned to the
pool. You can do this using either the
Close or Dispose methods of the
Connection object, or by opening all
connections inside a using statement
in C#, or a Using statement in Visual
Basic. Connections that are not
explicitly closed might not be added
or returned to the pool. For more
information, see using Statement (C#
Reference) or How to: Dispose of a
System Resource for Visual Basic. Ref.
You should appropriately wrap anything that implements IDisposable in a using statement block:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
...
command.ExecuteNonQuery();
}
Because (some) databases also hold open a connection until told by the calling app to close it. If you get hundreds of calls to a database then it's sitting there with 100 open connections tying up resources. It's not uncommon to have thousands or hundreds of thousands of calls to a database in a busy app, and sooner or later the DB performance will kill the app's performance.
It's really just common sense. If you have a valid reason to keep it open, then do so. If not, close it as soon as you're done with it. But it's better to be in the good habit of closing the connections so that you don't just leave them open when you don't intend to. It's a good habit like wearingyour seat belt or closing the refrigerator door when you're not getting food out.
This article states it well (even if it is a bit outdated):
http://www.bewebmaster.com/84.php
A common problem among hosting
companies is that ASP websites do not
close the database connections after
they are opened. This is a basic step
that you should consider to be part of
mandatory code. If you do not close
your database connections, many
problems can occur like web pages
hanging, slow page loads, and more.
Think of it as going through a door to
your house. Maybe the door will shut
by itself, but maybe it won't. If it
doesn't shut, who knows what will
happen. If you live in the country, a
bear could walk in. If you live in the
city, a mugger could walk in. Alright,
well maybe leaving a database
connection open won't lead to anything
that bad, but it will lead to a lot of
unnecessary headaches for both you and
your hosting company.
It is clear if you donot close the connection than it would consume your resource continuously and which would have overall impact on your apllication and it may also not be added or returned to the pool.
Back to basics.
I have an application written in c# and I am using the sqlClient to connect to database.
I have several methods and I usually open the connection in a try catch block
try{
**open connection**
//Mehod1()
//Method2()
........
}catch(exception){
//Do something
}finally{
**close connection**
}
The Problem is that there are a lot connections in pool.
I am using master page and in master page I am loading the menu from database (different menu for each user).
Then in main pages I open again a connection to get the rest data.
In the middle of the page it may be a method that need again to connect to database.
My Question is
Is this a good practise?
Am I doing something wrong?
Is there a better practise to avoid multiple connections?
What about singleton pattern?
Thanks in advance
SOLUTION
I found the reason!!!
I had forgot to close a connection.
I was sure that I had close it, but
sometimes you can't be so sure.
Thanks everyone for your responses
Since the connection is pooled you don't need to "reuse" it in different methods.
I use the following code:
using(SqlConnection connection = new SqlConnection("your-connectionstring"))
{
// Do your stuff here...
}
Using is just a short hand way of writting try-catch-finally. It is used for disposable objects.
And this can go into each method.
EDIT: Using the connection from the pool is not hurting performance either. All connection information are cached anyway. So just use the SqlConnection on an atomic level.
It's a good thing though to have the ConenctionString handling in a more generic way...
Using() as said above is a good way to new up a new object of a class that implements IDisposable. But with that being said , you cannot leave you connection open once you done. You have finite number of connection in the pool and leaving a connection unclosed can starve other SPIDs which are waiting for active connection which will finally timeout. So you should
Always have atomic and small transactions .
Close when done.
There is DAAB (data access application block) from Microsoft Enterprise Library which can be used as helper to open and close connections + do many other DB related tasks easily. Here it is
http://msdn.microsoft.com/en-us/library/cc511547.aspx
Probably you didn't dispose your SqlConnections
try this:
using (SqlConnection connection = new SqlConnection(connectionString))
{ }
this syntax will call method Dispose() automatically for you. Using statement details here
UPDATE:
A bit more info about this methods you may find here: Close, Dispose
Basically the difference is that method Dispose() called method Close(), but before it is cleaning some resources and removing connection from the pool details here.
As you see Dispose() doing a bit more than Close(). So if you going to reuse connection later use method Close() if not destroy that completely using method Dispose() which is automatically getting called if you using the syntax above.