Is it necessary to dispose SqlConnection as well as SqlCommand? - c#

Is it necessary to separately dispose of a SqlConnection as well as a SqlCommand?
I'm doing some maintenance work on an application and found the following code:
public void CallStoredProc(string storedProcName)
{
using (SqlCommand command = new SqlCommand(storedProcName, CreateConnection()))
{
command.CommandType = CommandType.StoredProcedure;
command.Connection.Open();
// Additional code here.
command.ExecuteNonQuery();
}
}
Will this clean up the SqlConnection properly, under normal circumstances as well as if there is an error? Or would we have to alter the code to something like:
public void CallStoredProc(string storedProcName)
{
using (SqlConnection connection = CreateConnection())
{
using (SqlCommand command = new SqlCommand(storedProcName, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Connection.Open();
// Additional code here.
command.ExecuteNonQuery();
}
}
}

yes , it is necessary to dispose the sqlconnection and sqlcommand object after your piece of code gets executed.
Now, there are two ways by which you can achieve this:
Write your code in using statement which will take care of disposing the objects, as sqlconnection and sqlcommand implements the IDisposable interface which takes care of disposing the objects..
by calling .close() method explicitly on sqlconnection object.

Yes, you will have to dispose (of) the connection separately. You can also see this in the source code: SqlCommand.Dispose() does not close or dispose the connection it uses (by the way, that would be bad anyway as you could not execute multiple commands with the same connection).

Related

Do I need to close and dispose the SQLConnection explicitly?

SqlDataReader rdr = null;
con = new SqlConnection(objUtilityDAL.ConnectionString);
using (SqlCommand cmd = con.CreateCommand())
{
try
{
if (con.State != ConnectionState.Open)
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(Parameter);
cmd.CommandText = _query;
rdr = cmd.ExecuteReader();
}
catch (Exception ex)
{
throw ex;
}
}
In this above code, sqlconnection is opened inside the managed code. Hence, will the connection object be disposed automatically upon ending the scope of USING?
You have to care about the disposal of SqlConnection, since it's a disposable object. You can try this:
using(var sqlConnection = new SqlConnection(objUtilityDAL.ConnectionString))
{
using (SqlCommand cmd = con.CreateCommand())
{
// the rest of your code - just replace con with sqlConnection
}
}
I suggest you replace the con with a local variable - if there isn't already (it does not evident from the code you have posted). There is no need for using a class field for this purpose. Just create a local variable, it would be far more clear to track it.
You should Dispose every temporary IDisposable instance you create manually, i.e. wrap them into using:
// Connecton is IDisposable; we create it
// 1. manually - new ...
// 2. for temporary usage (just for the query)
using (SqlConnection con = new SqlConnection(objUtilityDAL.ConnectionString)) {
// Check is redundant here: new instance will be closed
con.Open();
// Command is IDisposable
using (SqlCommand cmd = con.CreateCommand()) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(Parameter);
cmd.CommandText = _query;
// Finally, Reader - yes - is IDisposable
using (SqlDataReader rdr = cmd.ExecuteReader()) {
// while (rdr.Read()) {...}
}
}
}
Please, notice that
try {
...
}
catch (Exception ex) {
throw ex;
}
is at least redundant (it does nothing but rethrow the exception, while loosing stack trace) and that's why can be dropped out
In general:
In the .Net framework, nothing gets disposed automatically. Otherwise we wouldn't need the IDisposable interface. The garbage collector can only handle managed resources, so every unmanaged resource must be handled in code in the dispose method.
So as a rule, every instance of every class that is implementing the IDisposable must be disposed either explicitly by calling it's Dispose method or implicitly with the using statement.
As best practice, you should strive to use anything that implements the IDisposable interface as a local variable inside a using statment:
using(var whatever = new SomeIDisposableImplementation())
{
// use the whatever variable here
}
The using statement is syntactic sugar. the compiler translates it to something like this:
var whatever = new SomeIDisposableImplementation();
try
{
// use the whatever variable here
}
finally
{
((IDisposable)whatever).Dispose();
}
Since the finally block as guaranteed to run regardless of whatever happens in the try block, your IDisposable instance is guaranteed to be properly disposed.
With SqlConnection specifically, in order to return the connection object back to the connection pool, you must dispose it when done (the Dispose method will also close the connection, so you don't need to explicitly close it) - So the correct use of SqlConnection is always as a local variable inside the using statement:
using(var con = new SqlConnection(connectionString))
{
// do stuff with con here
}

Why must I use Dispose()?

Here is my code:
public void InsertData()
{
using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString))
{
using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection))
{
connection.Open();
command.ExecuteNonQuery();
}
}
}
But I found this code sample:
public void InsertData()
{
SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
command.ExecuteNonQuery();
command.Dispose();
connection.Close();
connection.Dispose();
}
why does the author use
command.Dispose()
and
connection.Dispose();
in their code?
using can only be used on objects that are disposable (which is when they implement the interface IDisposable). Doing so will automatically call Dispose on that instance. However in contrast to call it yourself the using-statement ensures that Dispose is also called when an exception whithin that block occurs. So it´s safer to use that approach.
Your first example is equivalent to this:
try
{
SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
try
{
command.ExecuteNonQuery();
}
finally
{
command.Dispose();
}
}
finally
{
connection.Dispose();
}
You'll have resource leak when exception has been thrown:
public void InsertData()
{
SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
command.ExecuteNonQuery(); // <- imagine that this throws exception
// and so these don't execute at all and you'll have two resources leaked:
// 1. Connection
// 2. Command
command.Dispose();
connection.Close();
connection.Dispose();
}
The reasons of the exception can vary:
1. Insert failed (e.g. invalid field value insertion)
2. User doesn't have privelege required
3. RDMBS Internal error
...
You can emulate using with try .. finally which is wordy:
public void InsertData()
{
SqlConnection connection = null;
try {
connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = null;
try {
command = new SqlCommand("Some Simple Insert Query", connection);
command.ExecuteNonQuery();
}
finally { // rain or shine, dispose the resource (if it has been created)
if (command != null)
command.Dispose();
}
}
finally { // rain or shine, dispose the resource (if it has been created)
if (connection != null)
connection.Dispose();
}
You don't have to use dispose in your example, because the using block does that for you.
See here: using Statement (C# Reference)
He is using connection.Dispose(); because the person is inexperienced and is writing bad code that is not safe. If a exception is thrown the connection will never be disposed of causing it to remain open till the GC collects the connection maybe minutes or hours later.
The using block is just syntactic sugar for the try/finally Dispose() pattern. This is all explained in the documentation.
Note you can also reduce the indentation in your code:
using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString))
using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection))
{
connection.Open();
command.ExecuteNonQuery();
}
In .Net IDisposable and the Dispose method are used to clean up unmanaged resources.
.Net keeps track of managed resources so it can clean them up automatically, but it needs to have some help when dealing with unmanaged resources.
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
https://msdn.microsoft.com/en-us/library/system.idisposable.dispose(v=vs.110).aspx
The using statement is a way to automatically call the Dispose method when you're done using it.
Provides a convenient syntax that ensures the correct use of IDisposable objects.
It'll even get called if an exception is called.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.
https://msdn.microsoft.com/en-us/library/yh598w02.aspx
The code which isn't using the using statements is incorrect.
It'll work most of the time, but if an exception occurs the unmanaged resources in SqlConnection could be left uncleaned.
As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement.

When does SqlCommand close when used in another function?

I have a program in C# where I created various class, and all of them need to make calls to the database. So I decided to create a static class that handles all the calls to allow me to apply far-reaching changes very easily. Within that class I have functions that call the various parts of SqlCommand (ExecuteReader(), etc) I finally got tired of rewriting all the connection code, and abstracted it out to another function called getSqlCommand() which just returns an initialized SqlCommand which I use to perform the various commands. I've chosen to not pass the SqlCommand back to the other programs (though it is a public method in case I need it) because there is some pre-processing if you will that I may do before I had the results back to the program.
My question is, if/when the SqlConnection closes? Since it is being passed back as a return value in a SqlCommand, will it be left open? and if so, can I close it? Here is some code (slightly stripped down) so you can see what I am doing, thanks in advance!
The function to create the SqlCommand:
public static SqlCommand GetSqlCommand(string query)
{
using (SqlConnection dbConnection = new SqlConnection( SQLConn )) {
dbConnection.Open();
SqlCommand cmd = new SqlCommand( query, dbConnection );
cmd.CommandTimeout = 0;
return cmd;
}
}
An example of the usage of the command in the static class:
public static SqlDataReader executeReader( string query )
{
try {
return GetSqlCommand(query).ExecuteReader();
} catch (SqlException) {
//Notify User and Resolve Error
}
return null;
}
A SqlConnection is closed when you call Dispose. Exiting the using block does that. The connection will be closed.
That's all there is to it. It will not magically stay open because ADO.NET does not know and cannot find out that you returned the connection object.
Move the connection out of the GetSqlCommand method. Pass the connection object into that method. GetSqlCommand has no business in creating a connection. It should take a connection, use it, but not close it.
The connection closes before the code exits the GetSqlCommand method. That means that the command object that it returns is useless.
The using construct creates a try ... finally block, where it disposes the connection at the end of the block. As disposing the connection also closes it, the connection is already closed before the command object is returned from the method to the caller.
The using keyword is equivalent to use try finally, and within the finally block your connexion will be disposed
SqlConnection dbConnection = new SqlConnection( SQLConn );
try
{
dbConnection.Open();
SqlCommand cmd = new SqlCommand( query, dbConnection );
cmd.CommandTimeout = 0;
return cmd;
}
catch(Exception ex)
{
}
finally
{
dbConnection.Dispose();
}
And even if there is a return statement inside a try block , the block finally will always be executed

Multiple using block c#

I am working on application in which i need to access database. Use of using statement is good because "using" statement is to ensure that the object is always disposed correctly, and it doesn't require explicit code to ensure that this happens. So i am little bit confused where to use "using" and where to not.
public int route(Route r)
{
try
{
using (SqlConnection con = new SqlConnection(connectionString))
{
using(SqlCommand com = new SqlCommand("",con))
{
using (SqlDataReader sdr = com.ExecuteReader())
{
}
}
}
}
catch (Exception e)
{
}
}
Any time an object you create implements IDisposable, disposing of it (with or without the using syntactic sugar) is a good idea.
The benefit of the using block syntactic sugar (over manual .Dispose() calls) is that Dispose() will still be called even if there is an exception and flow leaves the using block.
Also, note that you can stack up the usings, without nested indentation:
using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand com = new SqlCommand("",con))
using (SqlDataReader sdr = com.ExecuteReader()) // Still need to open connection ...
{
...
As an aside, a further benefit of using is that if the IDisposable variable is declared within the using, it that the variable is readonly and cannot be reassigned within the block, e.g.:
using (SqlDataReader sdr = com.ExecuteReader())
{
sdr = new SqlDataReader() // Error
You can simplify it like this:
using (SqlConnection con = new SqlConnection(connectionString))
using(SqlCommand com = new SqlCommand("",con))
using (SqlDataReader sdr = com.ExecuteReader())
{
...
}
Using statements are translated to try/finally blocks.Therefore your object will be Disposed even if there is an exception thrown.So if you have a Disposable object and you want to ensure that it will be Disposed after it's used, you can use using statements.Remember it's kind a syntactic sugar for this:
SqlCommand cmd;
try
{
cmd = new SqlCommand();
...
}
finally
{
((IDisposable)cmd).Dispose();
}
This looks okay as far as using blocks are concerned.
However, you should NOT use a try/catch block here, unless you intend on actually doing something with the exception. Otherwise you are just hiding possible errors away, which is dead wrong.

If SqlDataReader is going to be disposed, do I need to call close()?

If I instantiate a SqlDataReader inside a using block, do I need to call close() on the reader?
Simple example of looking up a user shown below.
using (var connection = new SqlConnection(Settings.GetValue("SqlConnection")))
{
SqlCommand command = new SqlCommand("select * from Users where Id = #Id", connection);
command.Parameters.Add("#Id", SqlDbType.UniqueIdentifier);
command.Parameters["#Id"].Value = id;
using (SqlDataReader reader = command.ExecuteReaderWithRetry())
{
reader.Read();
if (reader.HasRows)
{
//Do work
}
//Is this neccesary?
reader.Close();
}
}
If it's in a using block, then it is automatically closed. You do not need to explicitly close it.
BTW the SqlCommand in your example is disposable. You should create it in a using block too, otherwise any resources it controls won't be let go until the garbage collector collects.
Your undisposed SqlCommand is actually a good example of why C#'s emulation of RAII is not "real" RAII. You must take an explicit action (making blocks) for the RAII to kick in which is equivalent to an explicit close albeit with different syntax.

Categories