Do I need to close OleDbDataReader everytime I use it? - c#

I am using the OleDbDataReader class in my c# project and my program keep locking up my mdb file after it runs. I am wondering how do I close my connection reliably at the end to release the lock. And if I need to close it everytime I run a query or can I just do it all in one go at the end of the program. Here is how I am setting it up:
private OleDbConnection myDbC = new OleDbConnection(connectionString);
myDbC.Open();
And here is how I use it, many many times:
OleDbCommand cmd = new OleDbCommand(SQL, myDbC);
OleDbDataReader reader = cmd.ExecuteReader();
reader.Close();
When the program finishes, I also do the following:
myDbC .Close();
So this is somehow locking up the mdb file. Any help?

I suggest you to use using keyword. Because sometimes you can forget to close or dispose connection and reader. Because using automatically disposes object. Using statement tells .NET to release the object specified in the using block once it is no longer needed.
using (OleDbConnection conn = /* Create new instance using your favorite method */)
{
conn.Open();
using (OleDbCommand command = /* Create new instance using your favorite method */)
{
using (OleDbDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
//read here
}
}
}
conn.Close(); // Optional
}
Additional details from MSDN:
C#, through the .NET Framework common language runtime (CLR),
automatically releases the memory used to store objects that are no
longer required. The release of memory is non-deterministic; memory is
released whenever the CLR decides to perform garbage collection.
However, it is usually best to release limited resources such as file
handles and network connections as quickly as possible.
The using statement allows the programmer to specify when objects that
use resources should release them. The object provided to the using
statement must implement the IDisposable interface. This interface
provides the Dispose method, which should release the object's
resources.

It is always a good practice to .Close() connections. Do NOT rely on the Garbage Collector to do it for you. There are certain situations where the connection will automatically close for you; like when using a SqlDataAdapter and its .Fill() method. But that doesn't change the fact that you should manage your connections in your code.
That being said, this is best achieved with a using statement, like this:
using(OleDbConnection oledbConn = new OleDbConnection())
{
oledbConn.Open();
}
You can also nest these using statements, wrap command objects and even data adapters:
using(OleDbConnection oleDbConn = new OleDbConnection())
{
oleDbConn.Open();
using (OleDbCommand oleDbCmd = new OleDbCommand())
{
using (OleDbDataAdapter oleDbAdapter = new OleDbDataAdapter())
{
//More code can go here.
}
}
oleDbConn.Close();
}

Related

Does a SQL connection close with "using" if the connection comes from a static class?

Am I closing my SQL connection correctly, by placing it inside a "using" block?
This is how I grab a new connection, execute a query, and return the results:
using (SqlConnection objCS = DB.LMSAdminConn())
{
objCS.Open();
SqlCommand objCommand = new SqlCommand("SELECT TOP 1 * FROM users WHERE userid = #userid", objCS);
objCommand.Parameters.Add("#userid", SqlDbType.Int).Value = userid;
SqlDataReader reader = objCommand.ExecuteReader();
while (reader.Read())
{
//do something
}
reader.Close();
}
The connection itself comes from this call:
public static SqlConnection LMSAdminConn()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["lmsadmin"].ToString());
}
I am opening the connection inside a "using" block, and I thought that the connection would be closed as well, because it is opened inside the "using" block. But since the "new SqlConnection" object is actually generated from an outside class, is my connection still getting appropriately closed? SQL Server shows the connection as still being open, but I'm not sure if that is ADO.NET connection pool recycling / sharing, or if the connection is truly being held open. I don't explicitly call .Close() on the connection inside the "using" block.
Do I need to explicitly close the SqlCommand and SqlDataReader objects as well, or are they disposed when we leave the "using" block as well?
A using block is essentially syntactic sugar for having a try/finally block that calls the Dispose method of the object it is acting on, it doesn't matter where that object was created.
For a SqlConnection object, calling Dispose will close the connection. From the docs:
If the SqlConnection goes out of scope, it won't be closed. Therefore, you must explicitly close the connection by calling Close or Dispose. Close and Dispose are functionally equivalent.
Yes, it will close the connection once it loses scope.
Sample:
using (SqlConnection sqlConn = new SqlConnection("myConnectionString"))
{
sqlConn.Open();
...
}
This code will be converted into the following by the compiler :
try
{
SqlConnection sqlConn = new SqlConnection("myConnectionString");
sqlConn.Open();
...
}
finally
{
sqlConn.Close();
}
As you can see the close() is called in the finally block.
This finally block will force close the connection even if there is an exception during run-time within the using block.
You had an idea about connection pools - this is the right idea!
ADO.NET it is so beautiful that it tries to optimize everything and store it in connection pools. But we still need to always close connections!

How to keep single SQL Server connection instance open for multiple request in C#?

I have a Web API which contains database insert logic (ado.net) in C#. When multiple users (e.g. 100 users) call the Web API, every time a SQL Server connection is opened and closed for multiple requests. It slows down performance.
How can I keep a single SQL Server connection live for multiple requests? I have to keep SQL connection open only once and close after some time so that during that time it should consider multiple request and insert records in database.
Please suggest.
ADO.NET's SqlConnection is implementing a connection pool.
This means that when you close or dispose an instance of SqlConnection, the underlying connection simply returns to the pool. When another instance of SqlConnection is opened, and a connection is available in the connection pool, that connection will be used.
In fact, Microsoft docs page on SQL Server Connection Pooling clearly states:
Caution
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 or How to: Dispose of a System Resource for Visual Basic.
This means that the best practice way of using SqlConnection is this:
using(var con = new SqlConnection(connectionString))
{
// your sql stuff goes here...
}
BTW, SqlCommand, SqlDataReader and SqlDataAdapter also implements the IDisposable interface, so they too needs to be used in the context of the using statement:
using(var con = new SqlConnection(connectionString))
{
using(var cmd = new SqlCommand(sql, con))
{
// prepare command here - parameters and stuff like that
// either
using(var reader = cmd.ExecuteReader())
{
}
// or
using(var adapter = new SqlDataAdapter(cmd))
{
}
}
}
Well it's easy you just have to keep the connection open and if any readers opened they are closed.
var con = new SqlConnection("Your connection String");
con.open();
//your code
con.close()//after you have done your executions
Have you tried Linq. It does the same thing you want, it keeps the connection alive and i think it'll be easier for you

Trying to avoid nested SqlConnection

I'm not sure even if nested SqlConnections are possible but I would really like to stay away from it. I've run into a scope issue now in my code and I'm trying to figure out how to get around it.
So until recently I had a global SqlConnection which is opened when the application starts and closed when it finished. I've now discovered the concept of .NET's connection pool so I've changed my code such that every SqlCommand (or group of them) uses its own, freshly created and opened, SqlConnection, trusting .NET to manage the pool and the accompanying overhead.
The problem I'm now having is that I have several blocks of code that look something like this:
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand1 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand1.ExecuteNonQuery();
}
using (SqlCommand sqlCommand2 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand2.ExecuteNonQuery();
}
.
.
.
ClassGlobal.WriteAction(action);
}
while the ClassGlobal.WriteAction() function looks something like this:
public static void WriteAction(MyActionClass action)
{
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("Write the action to the DB", sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
}
}
As you can see, a new SqlConnection is created inside WriteAction() which is called from inside the scope of the first SqlConnection. Not good! I'm trying to avoid this.
In the past it wouldn't have been a problem seeing as there were none of these using (SqlConnection) blocks and all SqlCommands pointed to the same (global) SqlConnection. Obviously I could simply move my call to WriteAction() down below the closing curly brace of the using (SqlCommand) but:
The action instance that I pass to it is often instantiated and populated while inside the scope of the SqlConnection so I'd have to make more changes (lots of them) to move those out of the SqlConnection scope. There are loads of them and it will be hairy.
I'd actually prefer if the WriteAction() call could be inside the SqlConnection scope as in the example above so that I can wrap all of it in a TransactionScope, something that wasn't possible thus far but certainly seems like a good idea.
So here's what I plan on doing but I'd like to hear if any of you would consider this not to be good practice or whether you can suggest a better approach. (I've recently discovered that my global SqlConnection was not a good practice and it resulted in lots of time spent on fixing it. I'd like to avoid such a discovery in future).
How about I add a parameter to the WriteAction() function so that it looks as follows:
public static void WriteAction(MyActionClass action, SqlConnection sqlConnection)
{
using (SqlCommand sqlCommand = new SqlCommand("Write the action to the DB", sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
}
This means that, rather than moving the calls to WriteAction() outside of the SqlConnection scope, I can simply add the SqlConnection as a parameter to the function so that the SQLCommand inside the function make use of the same connection, even if that connection is enlisted to a TransactionScope.
For the few instances where I call WriteAction() from outside the scope of any SqlConnection, I can write an overloaded function that looks like this:
public static void WriteAction(MyActionClass action)
{
using (TransactionScope transactionScope = new TransactionScope())
{
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
WriteAction(action, sqlConnection);
}
transactionScope.Complete();
}
}
Does this look like a good idea or am I going to rue this decision in another two years?
Passing the SqlConnection instance to the method is absolutely fine. However, i'm not sure if you last approach, the overloaded method without the SqlConnection is a good idea. It hides the fact that you should better use the other, new overload. It makes the code compile which prevents you from fixing code which should be fixed now.
Note that the using block is not the problem but an opened connection. As long as you don't open the connection, the connection-pool does not need to open a physical connection.
So it is also a viable option to close the connection before you call WriteAction:
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand1 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand1.ExecuteNonQuery();
}
using (SqlCommand sqlCommand2 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand2.ExecuteNonQuery();
}
// ...
sqlConnection.Close();
ClassGlobal.WriteAction(action);
// ... perhaps open it again here
}
From MSDN:
Whenever a user calls Open on a connection, the pooler looks for an
available connection in the pool. If a pooled connection is available,
it returns it to the caller instead of opening a new connection. When
the application calls Close on the connection, the pooler returns it
to the pooled set of active connections instead of closing it. Once
the connection is returned to the pool, it is ready to be reused on
the next Open call.
So you can see that the nested using in WriteAction is not a problem so long as you don't keep the outer connection open. Don't confuse the connection instance with a physical connection.

How does the sql process behave?

From my C# program, I open the sql connection and do some updates to tables. After that I close the connection. And, If I check under Activity Monitor in Management Studio, New Process is created and even though I closed my sql connection from the program, the process is still there in Activity Monitor. May I know how this process behaves? Do we need to clear these processes explicitly? Thanks.
I think you are using the concept of process incorrectly here.
ADO.NET uses a connection pool. This means that when you call the Open method on a SqlConnection instance, you are not opening a new physical connection to the database, you are simply drawing one from the existing pool. And when you call Close you are not closing the connection, you are simply returning it to the connection pool for reuse.
The connection pool lives in the process of your application and is per connection string.
Do we need to clear these processes explicitly?
No, all you have to do is to ensure that you have wrapped all your IDisposable resources (such as as connections and commands) in using statements. This way you don't even need to be explicitly calling the Close method and the code will ensure that everything is properly disposed even in case of exception:
string connectionString = ...
using (var conn = new SqlConnection(connectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT id FROM foo";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(reader.GetOrdinal("id"));
Console.WriteLine(id);
}
}
}
Make sure you dispose the connection, your best bet is a using()-block.
using ( var con = new SqlConnection("???") )
{
using ( var cmd = con.CreateCommand() )
{
// do SQL with cmd
}
}

ado.net Closing Connection when using "using" statement

I am doing my database access methods to SQL Server like this
using (SqlConnection con = new SqlConnection(//connection string)
{
using (SqlCommand cmd = new SqlCommand(storedProcname, con))
{
try{
con.open();
//data reader code
}
catch
{
}
}
}
Do I need to be closing or disposing of SqlCommand, or will the using statement take care of that for me? I just don't want connection hanging open
Thanks
The using will take care of it for you. Under the hood, SqlConnection.Dispose() calls the SqlConnection.Close() method, and SqlCommand.Dispose() calls SqlCommand.Close().
As additional background, a using statement is syntactic sugar for a try ... finally that disposes the IDisposable object in the finally.
As an aside, you can make the code more concise and readable as follows:
using (SqlConnection con = new SqlConnection(/*connection string*/))
using (SqlCommand cmd = new SqlCommand(storedProcname, con))
{
//...
}
As Phil said, the using clause will take care of it for you. When compiled down it wraps the connection create in a try .. finally and places the connection disposal call inside the finally.
For more information you can see the using statement article at msdn.
Yes your code will close the connection, however that typcally means release back to the connection pool to be truely closed later.
If you execute this snippet of code, and then do an sp_who and observe that your connection is still there, that would be why.
If you absolutely need the connection truely closed (an edge case to be sure) then use the ClearAllPools
static method of ths SqlConnection
Using keyword will automatically close the connection for you
so you don't need to worry about calling connection.close() at the end every time.
when the scope
using (SqlConnection con = new SqlConnection(//connection string)
{
}
will over , connection will automatically be disposed by runtime. so don't worry
I think "using" was not required for SqlCommand. "Using" for SqlConnection would have done the job for you alone.
In fact you connection is submitted to Connection pool.

Categories

Resources