【问题标题】:using on SQLDataReader在 SQLDataReader 上使用
【发布时间】:2011-03-24 03:22:15
【问题描述】:

我知道我之前问过一个相关问题。我只是有了另一个想法。

using (SqlConnection conn = new SqlConnection('blah blah'))
{
    using(SqlCommand cmd = new SqlCommand(sqlStatement, conn))
    {
        conn.open();

        // *** do I need to put this in using as well? ***
        SqlDataReader dr = cmd.ExecuteReader() 
        {
            While(dr.Read())
            {
                //read here
            }
        }
    }
}

论据是:由于SqlDataReaderdr对象不是像连接或命令对象那样的新对象,它只是指向cmd.ExecuteReader()方法的引用,我需要把阅读器放在一个using。 (现在根据我之前的帖子,我的理解是任何使用IDisposable的对象都需要放在using中,而SQLDataReader继承自IDisposable,所以我需要放它。我是否正确根据我的判断?)我只是感到困惑,因为它不是一个新对象,在处理一个简单地作为命令的引用指针的对象时会导致任何问题吗?

非常感谢

【问题讨论】:

  • "cmd.ExecuteReader" 是一种方法参考。 “cmd.ExecuteReader()”(注意括号)是一个方法调用。

标签: c# dispose sqldatareader using-statement


【解决方案1】:

我认为你错了。 dr 是对cmd.ExecuteReader 返回的对象的引用,这将是一个新对象。在您的示例中,没有任何东西会处理 dr,所以是的,它需要在 using 中,或者手动处理。

您对 IDisposable 实现者需要using 中的判断是不正确的。他们将在外面正常工作。 using 语句只是 try ... finally 的语法糖。实现IDisposable 的事物应该调用Dispose,因为它们发出信号表明它们需要以确定性的方式处理某些状态。

请注意,如果您不致电Dispose,则并不总是有问题。一些对象还实现了终结器,它将由垃圾收集器触发。如果他们不实现终结器,他们可能会留下未回收的非托管内存。在您的应用程序关闭之前,这将保持未回收状态。所有托管内存最终都会被回收,除非它不符合垃圾回收条件。

重写:

using (SqlConnection conn = new SqlConnection('blah blah')) 
using(SqlCommand cmd = new SqlCommand(sqlStatement, conn)) 
{
   conn.open(); 
   using (SqlDataReader dr = cmd.ExecuteReader())
   { 
        while (dr.Read()) 
        { 
           //read here 
        } 
   } 
} 

【讨论】:

  • 是的,我知道 using 只是转换为 try..finally 块,我也可以自己调用 dispose。但我认为最好养成将块包装在 using 中的习惯,因为我可能倾向于忘记将代码块放入 try..finnally。谢谢回复。 :)
  • 没关系 :-) 我还要提一下,SqlDataReader 是一个新对象,或者至少是对方法调用返回的对象的引用,它不是对方法。之所以提到这一点,是因为您用大写字母指出了这一点,而且它不正确。阅读器和连接/命令之间的唯一区别是您初始化了连接/命令,但您没有初始化阅读器。最后,您仍然可以引用所有对象 - 无论您是否初始化它们。
  • 也许这不言而喻,但conn.Close(); 是在using(SqlDataReader dr=cmd.ExecuteReader()) { ... } 部分之后需要的,对吗?
  • @TrevorNestman Close 在 dispose 时调用,但如果您愿意,您也可以显式调用它。
  • @AdamHouldsworth 感谢您的回复/信息!我对 SqlConnection 很陌生,所以我正在尝试正确使用它。
【解决方案2】:

您应该将数据读取器包装在 using 语句中,因为 ExecuteReader 方法正在创建一个新的数据读取器实例,该实例也应该被处理掉。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 1970-01-01
    相关资源
    最近更新 更多