Does a C# using statement perform try/finally? - c#

Suppose that I have the following code:
private void UpdateDB(QuoteDataSet dataSet, Strint tableName)
{
using(SQLiteConnection conn = new SQLiteConnection(_connectionString))
{
conn.Open();
using (SQLiteTransaction transaction = conn.BeginTransaction())
{
using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM " + tableName, conn))
{
using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter())
{
sqliteAdapter.Update(dataSet, tableName);
}
}
transaction.Commit();
}
}
}
The C# documentation states that with a using statement the object within the scope will be disposed and I've seen several places where it's suggested that we don't need to use try/finally clause.
I usually surround my connections with a try/finally, and I always close the connection in the finally clause. Given the above code, is it reasonable to assume that the connection will be closed if there is an exception?

You are correct; the using statement compiles to a try / finally block.
The compiler transforms using(resource) statement; into the following code:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
(The cast to IDisposable is in case ResourceType implements IDisposable explicitly.

Yes, you either need to use a try/finally or a using statement. You don't need both.
A using statement is almost the same as a try/finally except that in C# 3 you can't reassign to the variable inside the using block.
using (IDisposable d = foo())
{
d = null; // Error: Cannot assign to 'd' because it is a 'using variable'
}
Previously you could reassign but the original object would still be disposed, not the newly assigned object and you would also get this compile warning:
Possibly incorrect assignment to local 'd' which is the argument to a using or lock statement. The Dispose call or unlocking will happen on the original value of the local.

Yes, the using statement is pretty much just shorthand for a try ... finally block.
For example, this code...
using (MyDisposableType foo = new MyDisposableType())
{
foo.DoSomething();
}
...would equate to the following...
{
MyDisposableType foo = new MyDisposableType();
try
{
foo.DoSomething();
}
finally
{
if (foo != null)
((IDisposable)foo).Dispose();
}
}

You can assume that the connection will be closed if you get an exception.

Using() ensures that the item instantiated within the parameters will be disposed of regardless of that happens within the associated code block. This includes closing the database connection assuming that SQLiteConnection handles its disposal correctly.

Related

Is it ok not to use using for transactions (in ADO.net)? Can I use snippet 2 instead of snippet 1? [duplicate]

I've been running into some problems concerning a SqlTransaction I'm using in my code. During my Googling I see many people using a using statement with a SqlTransaction.
What is the benefit and/or difference of using this type of statement with a SqlTransaction?
using (SqlConnection cn = new SqlConnection())
{
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}
Currently my code looks like this:
SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"]);
cn.Open();
SqlTransaction tr = cn.BeginTransaction();
try
{
//some code
tr.Commit();
cn.Close();
}
catch(Exception ex)
{
tr.Rollback();
cn.Close();
throw ex;
}
What is the advantage of one way over the other?
A using statement should be used every time you create an instance of a class that implements IDisposable within the scope of a block. It ensures that the Dispose() method will be called on that instance, whether or not an exception is thrown.
In particular, your code only catches managed exceptions, then destroys the stack frame by throwing a new exception instead of rethrowing the existing one.
The correct way to do it is:
using (SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"])) {
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction()) {
//some code
tr.Commit();
}
}
Note that if your class has instance members of types that implement IDisposable, then your class must implement IDisposable itself, and dispose of those members during its own Dispose() call.
The reason for this is that the SqlTransaction object will roll back in its Dispose() method if it was not explicitly committed (e.g. if an exception is thrown). In other words, it has the same effect as your code, just a little bit cleaner.
Essentially the using does the same thing that you are doing, except int a finally block instead of catching all exceptions:
using (SqlConnection cn = new SqlConnection())
{
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}
is the same as, just much less code :)
{
SqlConnection cn = null;
try
{
cn = new SqlConnection();
{
SqlTransaction tr = null;
try
{
tr = cn.BeginTransaction())
//some code
tr.Commit();
}
finally
{
if(tr != null && tr is IDisposable)
{
tr.Dispose();
}
}
}
}
finally
{
if(cn != null && cn is IDisposable)
{
cn.Dispose();
}
}
}
In the end, using is just a shortcut for a pattern. But it's a very useful and helpful shortcut, because it ensures you implement the pattern correctly and means you can do it with less code.
In this case, you haven't implemented the pattern correctly. What happens in your code if the call to tr.RollBack() also throws an exception?
The using statement is closing and disposing your connection and transaction for you. It's the equivalent of having a finally block on your try/catch that does the dispose.
You could also condense the using blocks down a bit like this...
using (SqlConnection cn = new SqlConnection())
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
which would be roughly the same as:
SqlConnection cn = null;
SqlTransaction tr = null;
try
{
cn = new SqlConnection());
tr = cn.BeginTransaction());
//some code
tr.Commit();
}
finally
{
if (cn != null)
cn.Dispose();
if (tr != null)
tr.Dispose();
}
If you don't use a using() block, you'll have to explicitly call the .Dispose() method of the SqlConnection and SqlTransaction objects. If you fail to do that, then unmanaged resources will not be released and could cause memory leaks or other problems.
Using using gurantees that your connection object will be disposed after the code returns. Dispose is useful to release unmanages resources, As a good practice, if an object implements IDisposable, dispose method always should be called
In addition to all that, it prettifies your code. Doesn't the 7 lines of code look better than the 14 lines? I breath a sign of relief every time I see a using block. It's like that little squirt of mist that comes out of that glad smelly thing. Mmm, I'm a pretty block of efficient code. Look at how well I manage memory and how pleasing I am to the eye.

Does initialising an object in "using" block disposes it of outside the block?

I have some code which looks like this:
Object o;
using (SqlConnection sql = GetSqlConnection) {
using (SqlCommand sqlCommand = GetSqlCommand()) {
using (Datareader dr = GetDataReader()) {
o = new Object();
while (dr.read()) {
//do something
}
}
if (o == null) // RESHARPER SAYS THAT THIS WILL ALWAYS BE TRUE
//do something
}
}
The place where I check for o == null, ReSharper says that this command will always be true. I don't understand this behaviour; do all the objects initialised in using block get disposed of, or only the ones which are created with using statement.
When the using block is closed, it will call Dispose() on that object, which, depending on the implementation of IDisposable, may set the object to null. However, "o" in your case isn't IDisposable or in a using block, and I'm willing to believe ReSharper has a bug in this case, because when I have the exact same code in my installation, it prompts me to replace
if(o == null)
with false, exactly the opposite of your problem.
If your code is exactly as written and Resharper is really complaining about the line you indicated, then it is wrong.
In fact, ReSharper has it exactly backwards: the comparison is redundant because it will never be true. You set o to a new Object() immediately, so it will never be null. The using block has no effect on the value of variables other than the one you put in the opening statement. Upon leaving a using block, that one instance is disposed of by calling IDisposable.Dispose on it, and it goes out of scope.
However, I do want to correct one huge misconception you seem to have: disposing of an object does not set it to null. The following code will still crash when it tries to close an already-disposed object:
var conn = new SqlConnection(GetConnectionString());
conn.Open();
conn.Dispose();
if (conn != null)
{
conn.Close();
}
"Being disposed" is a condition that applies to instances of objects; it means their resources have been cleaned up and they cannot be safely used anymore. "Being null" is a condition that applies to variables; it means they do not reference any instance of their defined type, disposed-of or otherwise.
The using keyword and IDisposable interface are using to manage the is-disposed-of state of instances of objects. They have no effect on the is-a-null-value state of variables in your program.
Does initialising an object in “using” block disposes it of outside
the block?
No. Here is proof.
The object you're using will be disposed, of course (that's the whole point of using), but things done within the block aren't affected. This is a new scope, though, so you'd get the warning with this code:
Object o;
using (SqlConnection sql = GetSqlConnection) {
using (SqlCommand sqlCommand = GetSqlCommand()) {
using (Datareader dr = GetDataReader()) {
Object o = new Object();
while (dr.read()) {
//do something
}
}
if (o == null) // RESHARPER SAYS THAT THIS WILL ALWAYS BE TRUE
//do something
}
}
(note the declaration of a second object o in the inner scope).

Can I combine a using() {} block with a method's out parameter?

Given a method
public static bool Connection.TryCreate(out Connection connection) {}
And a piece of calling code:
Connection connection;
if (!Connection.TryCreate(out connection))
// handle failure gracefully.
/*
* work with connection
*
* …
*
*/
connection.Dispose();
I'm using the same pattern as bool.TryParse and friends, i.e. TryCreate returns whether the operation was successful.
I realize the using() variable needs to be read-only within its block, but is there a way to turn the above into a using() {} block (TryCreate only sets it once), like so:
using (Connection connection)
{
if (!Connection.TryCreate(out connection))
// this would leave the using() block prematurely
/*
* work with sconnection
*
* …
*
*/
}
(This doesn't compile:
error CS1657: Cannot pass 'connection' as a ref or out argument because it is a 'using variable'
)
No, that is not possible.
The using (x) {...} construct makes a copy of x when it enters the block, so you can do this:
var x = new FileStream(...);
using (x)
{
x = null;
}
The stream will still be disposed when the using block ends.
The corollary is that this won't work either:
Stream x = null;
using (x)
{
x = new FileStream(...);
}
here the stream you construct inside the using block will not be disposed.
What you can do, however, is this:
Connection connection;
if (Connection.TryCreate(out connection))
using (connection)
{
}
In C# 7.0 and onwards you can combine this with "out variables" to form:
if (Connection.TryCreate(out var connection))
using (connection)
{
}
Looks like a bad use of the Try* pattern (some would argue this is an anti-pattern).
Instead of a TryCreate, just have a Create method that throws an exception if not successful and that returns the created connection.
Then you could do the usual:
using(Connection connection = Connection.Create())
{
}
Alternatively, if you want to avoid an exception being thrown and the required try{}catch{}, have the Create method return null when a connection could not be created and test for that.
You can do it like this:
Connection connection;
if (Connection.TryCreate(out connection))
{
using (connection)
{
…
}
}
But it might be better if you just returned null on failure:
using (Connection connection = Connection.Create())
{
if (connection != null)
{
…
}
}
The finally block that is created by the using checks whether connection is null and doesn't do anything if it is.
Also, if you're not declaring the variable in the using, then it doesn't have to be read-only.
No. If you are concerned about exceptions in the gap between a method call and the using, you could use try/finally:
Connection conn = null;
try {
if(!conn.TryCreate(out conn)) return;
...
} finally {
if(conn != null) conn.Dispose();
}
A step sideways ?
public class ConnectTo : IDisposable
{
public Connection CurrentConnection {get; private set;}
public ConnectTo()
{
CurrentConnection = null;
// Connect up to whatever.
}
#region IDisposable
// Blah blah
#endregion
}
then
using( ConnectedTo conn = new ConnectTo())
{
if (conn.CurrentConnection != null)
{
//Do Stuff
}
}

When I have a return within the code of Using(connection) does the connection and db objects gets dismissed properly

I'm not sure if my question is clear so here's a code sample:
public static bool isRecordExist(int ID)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
int flag = int.Parse(command.ExecuteScalar);
if (flag)
return false;
else
return true;
}
}
}
So, now I understand that I don't need to close or dismiss any Sql objects when I have the 'using' keyword, because it does that automatically as soon as you get our of it's brackets but now the we reach to the 'return' part. will it dismiss and close the objects properly or do I need to save this value and make my check and 'return' outside the 'using' code ?
Yes it closes automatically. Exiting a using block calls .Dispose() on the object in question which for a SqlConnection will close the connection and any open resources.
Does End Using close an open SQL Connection
Yes, the connection will be closed.
Note that this can cause problems. Say, for example, that you want to return a DataReader from the function. As soon as you return the datareader, the connection that your reader depends on is closed by the using block and you can't read any records. In those situations, I use either a delegate or an iterator block to get around the problem, depending on what I'm doing.
Yes, the object will be disposed properly. If you take a look at the IL generated from the method, you will see a try/finally block in the appropriate spots of your using { ... } statements. Exiting the method from any part inside of a using { ... } block will always follow the try/finally dispose pattern.
I also would recommend stacking your using statements like this:
using (SqlConnection connection = new SqlConnection(ConnectionString))
using (SqlCommand command = new SqlCommand(commandText, connection))
{
//some work
}
It generally makes the code more readable, especially if you are using 4 or 5 of them.
Yes, because it is syntactic sugar for try/finally without the catch.
So when you do this:
using (SqlConnection connection = new SqlConnection ...) {
code code code then return;}
You get (approximately) this behind the scenes:
SqlConnection connection;
connection = null;
try
{
connection = new SqlConnection ...;
code code code then return;
}
finally
{
if (connection != null) connection.dispose();
}
And by the definition of finally, it is always called, no matter how you break out of the try block (usually you think 'exception' but also including return).

nested using statements - which one wont get disposed

If i have some code like this and an error occurs in the second using statement, will the dispose method on 1st using not be called?
using (System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(cnstr))
{
cn.Open();
using (SqlTransaction tran = cn.BeginTransaction(IsolationLevel.Serializable))
{
--EDIT--
Also is it better to write Try / Finally block or using statement. Internally compilter will generate Try / Finally for using statement but as per coding standards which one is better?
No, both will be called. Just because an exception is called in the inner statement, doesn't mean that the first is ignored.
a using statement is just another syntax for:
var iDisposableItem = new Item();
try
{
......
}
finally
{
iDisposableItem.Dispose();
}
so in your example:
var iDisposableItem = new Item();
try
{
var iDisposableItem2 = new Item();
try
{
throws exception
}
finally
{
iDisposableItem2 .Dispose();
}
}
finally
{
iDisposableItem.Dispose();
}
Now what should be noted and what you have to be careful about is that whatever caused the first exception could cause problems with the outer using statement when it calls Dispose(). The exception could throw the (really either) object into a faulted state and calling Dispose might result in another different exception which "masks" the first one. This is a gotcha in WFC when using using statements: http://msdn.microsoft.com/en-us/library/aa355056.aspx
A using statement is nothing but a try/finally in disguise, unless the process is forcibly terminated, your objects will be disposed of correctly.
In other words, this:
using (Type1 x = new Type1())
{
// a
using (Type2 y = new Type2())
{
// b
}
// c
}
Is actually similar to this (this is simplified):
Type1 x = new Type1();
try
{
// a
Type2 y = new Type2();
try
{
// b
}
finally
{
y.Dispose();
}
// c
}
finally
{
x.Dispose();
}
It will dispose both, and you can shorten it like:
using (SqlConnection cn = new SqlConnection(cnstr), SqlTransaction tran = cn.BeginTransaction(IsolationLevel.Serializable))
{
cn.Open();
}

Categories