C# Using与Try..Finally 语句(转)

转自:http://www.cnblogs.com/miniwiki/archive/2010/05/13/1734307.html

Using实质是编译器生成Try{} Finally{},保证Finally始终执行。


复制代码
1  SqlDataReader   Func()
 
2          {
 
3  
 
4               using  (SqlConnection conn = new  SqlConnection())
 
5              {
 
6                  conn.Open();
 
7                   using  (SqlCommand comm = new  SqlCommand())
 
8                  {
 
9                       // ............省略若干初始化
10                      SqlDataReader dr =  comm.ExecuteReader();
11                       return  dr;
12                  }
13                  
14              }
15          }
复制代码
本以为return了之后using就不会dispose对象了,没想到返回的SqlDataReader已经关闭连接了。于是查了查MSDN看到下面一段示例:

复制代码
使用using语句实际上生成的IL代码中是一个try, finally代码块,在finally代码块里释放资源。

比如这样一段代码:

            
using  (SqlConnection conn  =   new  SqlConnection())
            {
                conn.Open();
                
throw   new  Exception( " Exception!! " ); // 抛出异常之后能回收SqlConnection对象的资源吗?
            }

IL 代码可为:

  
//  Code size       42 (0x2a)
  .maxstack   2
  .locals init ([
0 class  [System.Data]System.Data.SqlClient.SqlConnection conn,
           [
1 bool  CS$ 4 $ 0000 )
  IL_0000:  nop
  IL_0001:  newobj     instance 
void  [System.Data]System.Data.SqlClient.SqlConnection::.ctor()
  IL_0006:  stloc.
0
  .
try
  {
    IL_0007:  nop
    IL_0008:  ldloc.
0
    IL_0009:  callvirt   instance 
void  [System.Data]System.Data.Common.DbConnection::Open()
    IL_000e:  nop
    IL_000f:  ldstr      
" Exception!! "
    IL_0014:  newobj     instance 
void  [mscorlib]System.Exception::.ctor( string )
    IL_0019:  
throw
  }  
//  end .try
   finally
  {
    IL_001a:  ldloc.
0
    IL_001b:  ldnull
    IL_001c:  ceq
    IL_001e:  stloc.
1
    IL_001f:  ldloc.
1
    IL_0020:  brtrue.s   IL_0029
    IL_0022:  ldloc.
0
    IL_0023:  callvirt   instance 
void  [mscorlib]System.IDisposable::Dispose()
    IL_0028:  nop
    IL_0029:  endfinally
  }  
//  end handler 

可以看到调用了SqlConnection的Dispose方法释放了资源。
复制代码

说明using语句不论语句块里面是否return,均会生成资源释放的代码。Try。。Finally块也一样,也是先执行完Finally,再执行try里面可能有的return;

 

下面的代码证实了这一点:


复制代码
class  Program
    {
        
static   void  Main( string [] args)
        {
            
using  (UsingTest ut =   testFunc())
            {
                
            }  

        }

      
static  UsingTest  testFunc()
       {
           
try {
               UsingTest ut 
=   new  UsingTest();
               
return  ut;
           }
          
finally
            {

                Console.WriteLine(
" finally... " );
                
            }
           
return   null ; // 这里的代码始终无法访问到,说明try里面的return实际上是执行完finally后立即执行的
       }
    }

    
internal   class  UsingTest:IDisposable
    {


      
public   UsingTest()
        {
            Console.WriteLine(
" Constructing... " );
        }
      
public    void  Dispose()
       {
           Console.Write(
" Disposing..... " );
       }
    }
复制代码

程序输出:

 

"Constructing..."

"finally..."

"Disposing....."

转载于:https://www.cnblogs.com/zcm123/archive/2013/06/02/3113623.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值