如何在异常时关闭DataReader

时间:2011-07-05 20:13:09

标签: c# .net-1.1 sqldatareader sqlcommand

我在数据层的某些方法中有以下代码:

StringBuilder sb = new StringBuilder();
SqlCommand s = new SqlCommand(sb.ToString(), conn);
try 
{ 
    SqlDataReader dr = s.ExecuteReader(); 
    while(dr.Read())
      DoSomething(dr);
}
catch (Exception ex)
{ 
    sb.Append(Util.ExceptionRecursive(ex)); 
}
事情是,博士在例外的情况下永远不会关闭。当其他方法尝试访问另一个数据读取器时,它会抛出另一个异常,例如“另一个Datareader连接到数据库”

我想在任何情况下关闭我的DataReader。 但是这个:

sb = new StringBuilder();
SqlCommand s = new SqlCommand(sb.ToString(), conn);
SqlDataReader dr;
try 
{
    dr = s.ExecuteReader(); 
    while(dr.Read())
      DoSomething(dr);
}
catch (Exception ex)
{ 
    sb.Append(Util.ExceptionRecursive(ex)); 
}
finally
{
    dr.Close();
}

不会起作用,因为如果异常dr可能没有数据,并且不会编译。

那我该怎么办呢?

3 个答案:

答案 0 :(得分:9)

您应该使用using statement
它会生成finally块,以确保始终处置您的资源。

StringBuilder sb = new StringBuilder();
using (SqlCommand s = new SqlCommand(sb.ToString(), conn)) {
    try 
    { 

        using (SqlDataReader dr = s.ExecuteReader()) {
            while(dr.Read())
              DoSomething(dr);
        }

    }
    catch (Exception ex)
    { 
        sb.Append(Util.ExceptionRecursive(ex)); 
    }    
}

答案 1 :(得分:3)

最好的方法可能就是:

sb = new StringBuilder();
...
using (SqlCommand s = new SqlCommand(sb.ToString(), conn))
using (SqlDataReader dr = s.ExecuteReader())
{
    try
    {
        while(dr.Read())
          DoSomething(dr);
    }
    catch (Exception ex)
    { 
        sb.Append(Util.ExceptionRecursive(ex)); 
    }
}

但是,如果您在SQL执行期间期望(或不期望)异常,则必须将异常处理代码放在外面:

sb = new StringBuilder();
...
try
{
    using (SqlCommand s = new SqlCommand(sb.ToString(), conn))
    using (SqlDataReader dr = s.ExecuteReader())
    {
        while(dr.Read())
          DoSomething(dr);
    }
}
catch (Exception ex)
{ 
    sb.Append(Util.ExceptionRecursive(ex)); 
}

答案 2 :(得分:0)

你可以把它写成:

if(dr!=null) dr.Close();