如何在异常时关闭 DataReader

发布于 2024-11-18 17:49:57 字数 783 浏览 2 评论 0原文

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

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

问题是,如果出现异常,dr 永远不会关闭。当其他方法尝试访问另一个数据读取器时,它会抛出另一个异常,内容类似于“另一个数据读取器已连接到数据库”

我想在任何情况下关闭我的数据读取器。 但这:

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 可能没有数据,并且无法编译。

那我该怎么办呢?

I have the following code in some methods of my Data Layer:

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

The thing is, dr never closes in case of exception. And when other method tries to access another data reader, it throws another exception that says something like "Another Datareader is connected to the Database"

I want to close my DataReader in any case.
But this:

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

Won't work because in case of exception dr may have no data, and won't compile.

How should I do it then?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

高冷爸爸 2024-11-25 17:49:57

您应该使用 using 语句
它生成一个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)); 
    }    
}

You should use the using statement:
It generates a finally block to ensure that your resource is always disposed.

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)); 
    }    
}
雨落□心尘 2024-11-25 17:49:57

最好的方法可能是这样的:

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

The best way is probably this:

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

However, if you're expecting (or not) exceptions during SQL execution, you must place the exception handling code outside:

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)); 
}
┼── 2024-11-25 17:49:57

你可以将其写为:

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

you can write it as:

if(dr!=null) dr.Close();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文