How should I correctly dispose of an object? - c#

I frequently use the following code (or alike) to dispose of objects:
SqlCommand vCmd = null;
try
{
// CODE
}
catch(Exception ex) { /* EXCEPTION HANDLE */ }
finally
{
if (vCmd != null)
{
vCmd.Dispose();
vCmd = null;
}
}
Is this the best way to release objects and dispose of objects?
I'm using the VS analytics and give me a warning about redundancies. But I always do it this way...

The best way in terms of readability is using the using statement:
using(SqlCommand vCmd = new SqlCommand("...", connection)
{
try
{
// CODE
}
catch(Exception ex)
{
// EXCEPTION HANDLE
}
}
It disposes objects even in case of error, so similar to a finally. You should use it always when an object implements IDisposable which indicates that it uses unmanaged resources.
Further reading:
Cleaning Up Unmanaged Resources
there is no need to set objects to null.

Here is an example from MSDN:
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
}
Note the use of "using" for the connection.
Back in the Olden Days of COM/ActiveX, you needed to set your objects to "Nothing".
In managed code, this is no longer necessary.
You should neither call "Dispose()", nor set your sqlCommand to "null".
Just stop using it - and trust the .Net garbage collector to do the rest.

Related

Encapsulating and Disposing SqlClient Objects In Order

I am trying to layer my Sql client object calls such that they get disposed of reliably. Something like this:
Open database connection -> Create command -> Read results -> close
command -> close database connection
So far this has succeeded when I do all of these things in the same method.
The problem is this is error prone. And a mess to read through.
When I try to create a common method to handle this that cleans up everything and returns a reader the connection gets closed before the reader starts.
//closes connection before it can be read...apparently the reader doesn't actually have any data at that point ... relocating to disposable class that closes on dispose
public SqlDataReader RunQuery(SqlCommand command)
{
SqlDataReader reader = null;
using (var dbConnection = new SqlConnection(_dbConnectionString))
{
try
{
dbConnection.Open();
command.Connection = dbConnection;
reader = command.ExecuteReader(); // connection closed before data can be read by the calling method
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
dbConnection.Close();
}
}
return reader;
}
I can get around this by creating my own class that implements IDispose (etc) but then when I wrap it with the same using statement it takes up just as many lines as a database connection using statement.
How can I take care of the data base connection in a repeatable class that takes care of all these artifacts and closes the connection?
You could create a class that holds an open database connection that is reusable, but I suggest reading the data into a list and returning the result:
public List<object> RunQuery(SqlCommand command)
{
List<object> results = new List<object>();
using (var dbConnection = new SqlConnection(_dbConnectionString))
{
try
{
dbConnection.Open();
command.Connection = dbConnection;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Repeat for however many columns you have
results.Add(reader.GetString(0));
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
return results;
}
I don't know the structure of your data, but the important point is that you need to read your data (reader.GetString does this) before you dispose of the connection. You can find more information on how to properly read your data here.
Edit: As mentioned, I removed your finally statement. This is because your using statement is essentially doing the same thing. You can think of a using statement as a try-finally block. Your disposable object will always be disposed after the using statement is exited.
so there's no way to make a reusable method that tucks away all/most of the nested using statements?
There is a specific pattern supported for returning a DataReader from a method, like this:
static IDataReader GetData(string connectionString, string query)
{
var con = new SqlConnection(connectionString);
con.Open();
var cmd = con.CreateCommand();
cmd.CommandText = query;
var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return rdr;
}
Then you can call this method in a using block:
using (var rdr = GetData(constr, sql))
{
while (rdr.Read())
{
//process rows
}
} // <- the DataReader _and_ the connection will be closed here

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
}

Database Connection from another class

I have created a class in my program to handle database connection. This class includes a method named OpenConnection() to open the connection to the database. I'm not convinced that my program meets the standard of clean code. Here is the method.
public void OpenConnection()
{
if(connection==null || connection.State != Connection.Open)
{
connection = new OracleConnection(this.connectionString);
connection.Open();
}
}
This method works okay but I just want to make sure if this is a safe way and I am not exploiting my program in any way. Thank You in advance
Update
I also added the following methods in the class to close the connection and dispose it.
public void CloseConnection()
{
if (dbconnect != null | dbconnect.State != ConnectionState.Closed)
{
dbconnect.Close();
}
}
//Here the IDsiposable method is implemented
public void Dispose()
{
CloseConnection();
}
You can use using clause and it's going to handle the Dispose automatically.
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#EmployeeID", 123));
command.CommandTimeout = 5;
command.ExecuteNonQuery();
connection.close();
}
Your solution as coded seems ok if you add the cases suggested in this answer and if it's meant to be used on a single thread and within a very limited scope. That said it appears like you are gearing up to use this class as a parameter across many method calls because you want to
mix business logic and persistence concerns
or share an instance in such a way that other methods don't have to be concerned about whether to open the connection (e.g. a higher call in the call stack has not yet called Open) or not (e.g. a prior call in the call stack did open the connection (what we'd call an "ambient" connection)).
Either of these strategies usually leads to trouble. It's better to keep the scope small, where you know the connection is open and when to close it:
using (var connection = new OracleConnection(...))
{
connection.Open();
...
}
When you have this small scope, your abstraction now provides no value.
You have a possible resource leak owing to the fact that OracleConnection implements IDisposable. Also, calling close on a connection in ConnectionState.Executing or Fetching could be bad as it will rollback all uncommitted transactions.
public void OpenConnection()
{
if (connection == null)
{
connection = new OracleConnection(this.connectionString);
connection.Open();
return;
}
switch (connection.State)
{
case ConnectionState.Closed:
case ConnectionState.Broken:
connection.Close();
connection.Dispose();
connection = new OracleConnection(this.connectionString);
connection.Open();
return;
}
}

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.

Performance comparison between using block and Dispose method

Think about these 2 snippets:
Approach 1: use using statement
using(var connection = new SqlConnection())
using(var command = new SqlCommand(cmdText, connection)){
try{
connection.Open();
using(var reader = command.ExecuteReader(
CommandBehavior.CloseConnection | CommandBehavior.SingleResult){
while(reader.Read())
// read values
}
} catch (Exception ex) {
// log(ex);
}
}
Approach 2: use try/finally
var connection = new SqlConnection();
var command = new SqlCommand(cmdText, connection);
SqlDataReader = null;
try{
var reader = command.ExecuteReader(
CommandBehavior.CloseConnection | CommandBehavior.SingleResult);
while(reader.Read())
// read values...
} catch (Exception ex) {
// log(ex);
} finally {
command.Dispose();
if (reader != null) {
if (!reader.IsClosed)
reader.Close();
reader.Dispose();
}
if (connection.State != ConnectionState.Closed)
connection.Close();
connection.Dispose();
}
We all know that the using statements would be compiled to try/finally blocks. So is it correct to say: when the app get compiled, there would be 4 try blocks?
try { // for using SqlConnection
try { // for using SqlCommand
try { // my own try block
try { // for using SqlDataReader
} finally {
// dispose SqlDataReader
}
} catch {
// my own catch. can be used for log etc.
}
} finally {
// dispose SqlCommand
}
} finally {
// dispose SqlConnection
}
And, if the answer is yes, wouldn't that be a performance issue? Generally, is there any, I mean any performance difference between using blocks and try/finally blocks?
UPDATE:
From comments, I've to say:
1- The important question is, having multiple try blocks inside each other: is there any performance issue?
2- I have to care of code, because I'm responsible to code, not to query. The query-side has its own developer which is doing his best. So, I have to do my best too. So, it's important to me to take care of milliseconds ;) Thanks in advance.
Usually when you hear about try/catch is slow, it's all about exception handling. So if exception occurs then it might be slow. But just entering in try method is not something you should worry about. Especially in your case when you warp SQL query call.
If you want to know more about exceptions and performance in .NET you can find a lot of articles to read. For example: MSDN article or great CodeProject article.
And of course using is preferable way because it makes code much cleaner.

Categories