nested using statements - which one wont get disposed - c#

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();
}

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.

Is is right to return a method inside a "using(object that implements iDisposable)" statment? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
If I return a value inside a using block in a method, does the using dispose of the object before the return?
I have this code (simplyfied):
bool method1()
{
using (OleDbConnection con = new OleDbConnection(connString))
{
bool b = false;
try
{
con.Open();
b = true;
}
catch (Exception)
{
b = false;
}
finally
{
con.Close();
return b;
}
}
}
I return before the closing curly bracket of the "using" statment. Does my object "con" gets Disposed anyway? Is is better to use the following code?:
bool method1()
{
bool b = false;
using (OleDbConnection con = new OleDbConnection(connString))
{
try
{
con.Open();
b = true;
}
catch (Exception)
{
b = false;
}
finally
{
con.Close();
}
}
return b;
}
The whole point of the using statement is that it automates the disposal of an object, even if an unhandled exception is thrown from within the using block.
Therefore, once your code exits the using block, whether it's returning or otherwise, then the object being 'used' us disposed.
It is completely safe to return during a using statement due to the .NET magic of automatically handling disposal of objects. The whole idea is that you don't have to think about how you exit out of the using block, you just know that when you leave it the object will be disposed correctly. Because of such, your example could be simplified to this:
bool method1()
{
using (OleDbConnection con = new OleDbConnection(connString))
{
try
{
con.Open();
return true;
}
catch (Exception)
{
return false;
}
}
}
con.Close() can be removed as well as it is automatically called by the disposal.
Look at this if you want to see what happens under the hood.
there is no difference between two code sections; con object will be disposed in both examples.
In the first example you set a temporary variable and return that.
About the return in the finally: What happens after compilation is that you branch to the end of the method and then return a temporary variable.
E.g. the results is exactly the same. Just for clarity I would personally prefer the first one, because it resembles what happens more exactly.
using expands into somewhat more complex with additional if statement like
OleDbConnection con = new OleDbConnection(connString)
try
{
con.Open();
}
finally
{
// Check for a null resource.
if (con != null)
// Call the object's Dispose method.
((IDisposable)con).Dispose();
}
So in your example you might get NullReferenceException in finally block.
So if you want to return the status of operation and Dispose and object, I suggest to use this code snippet
using(OleDbConnection con = new OleDbConnection(connString))
{
try
{
con.Open();
return true;
}catch(OleDbException ex)
{
//log error
return false;
}
}

C#: "using" directive and try/catch block

I know how to use try/catch block in case of database calls and know how to use "using" directive in context of using try/finally construction as well.
But, can I mix them? I mean when I use "using" directive can I use try/catch construction as well because I still need to handle possible errors?
You can definitely use both together.
A using block is basically just a bit of syntactic sugar for a try/finally block and you can nest try/finally blocks if you wish.
using (var foo = ...)
{
// ...
}
Is roughly equivalent to this:
var foo = ...;
try
{
// ...
}
finally
{
foo.Dispose();
}
Of course you can do it:
using (var con = new SomeConnection()) {
try {
// do some stuff
}
catch (SomeException ex) {
// error handling
}
}
using is translated by the compiler into a try..finally, so it's not very different from nesting a try..catch inside a try..finally.
This one is perfectly valid:
using (var stream = new MemoryStream())
{
try
{
// Do something with the memory stream
}
catch(Exception ex)
{
// Do something to handle the exception
}
}
The compiler would translate this into
var stream = new MemoryStream();
try
{
try
{
// Do something with the memory stream
}
catch(Exception ex)
{
// Do something to handle the exception
}
}
finally
{
if (stream != null)
{
stream.Dispose();
}
}
Of course this nesting works the other way round as well (as in nesting a using-block within a try...catch-block.
A using such as:
using (var connection = new SqlConnection())
{
connection.Open
// do some stuff with the connection
}
is just a syntactic shortcut for coding something like the following.
SqlConnection connection = null;
try
{
connection = new SqlConnection();
connection.Open
// do some stuff with the connection
}
finally
{
if (connection != null)
{
connection.Dispose()
}
}
This means, yes, you can mix it with other try..catch, or whatever. It would just be like nesting a try..catch in a try..finally.
It is only there as a shortcut to make sure the item you are "using" is disposed of when it goes out of scope. It places no real limitation on what you do inside the scope, including providing your own try..catch exception handling.

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
}
}

Does a C# using statement perform try/finally?

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.

Categories