• 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 ([
    0class [System.Data]System.Data.SqlClient.SqlConnection conn,
               [
    1bool 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....."

  • 相关阅读:
    poj 3613(经过N条边的最短路)
    poj 3328(多起点多终点的最短路)
    poj 3311(floyd+状态压缩)
    新CCIE笔记-IP网络基础
    新CCIE笔记-IP网络基础
    算法之【冒泡排序法】
    算法之【冒泡排序法】
    算法之【冒泡排序法】
    算法之【辗转相除法】
    算法之【辗转相除法】
  • 原文地址:https://www.cnblogs.com/zcm123/p/3113623.html
Copyright © 2020-2023  润新知