Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nested using statements - which one wont get disposed

Tags:

c#

.net

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?

like image 901
Asdfg Avatar asked May 19 '11 17:05

Asdfg


2 Answers

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

like image 189
kemiller2002 Avatar answered Nov 08 '22 19:11

kemiller2002


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();
}
like image 22
Lasse V. Karlsen Avatar answered Nov 08 '22 19:11

Lasse V. Karlsen