在SQLDataReader上使用

时间:2010-08-02 10:14:27

标签: c# dispose sqldatareader using-statement

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

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

参数是:由于SqlDataReader dr对象不是连接或命令对象的新对象,它只是指向cmd.ExecuteReader()方法的引用,我需要吗?把读者放在using里面。 (现在根据我之前的帖子,我的理解是,使用IDisposable的任何对象都需要放在using中,SQLDataReader继承自IDisposable,所以我需要说的。我的判断是否正确?)我只是感到困惑,因为它不是一个新的对象,它会在处理一个只是指向命令的引用指针的对象时引起任何问题吗?

非常感谢

2 个答案:

答案 0 :(得分:26)

我认为你错了。 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 
        } 
   } 
} 

答案 1 :(得分:2)

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