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.
Related
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
}
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.
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).
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.
Does placing a SqlCommand.Connection in a using block close the connection in the same way as placing the SqlConnection in it's own using block? (Is #1 = #2)
Example 1
using (var cmd = GetCommandWithConnectionSetInternally(connString))
{
using (cmd.Connection)
{
}
}
Example 2
using(var conn = new SqlConnection(connString))
{
using(var cmd = new SqlCommand(cmdText, conn))
{
}
}
So, does the connection in Example 1 get closed as it would in Example 2 upon exiting the "using" block?
I can't see it working any other way since using is just a short form of try {} finally {} with a Dispose call in the finally block. Since the resource object being used is cmd.Connection, it should get disposed.