如果您已经关闭了SqlConnection,是否需要关闭/处理SqlDataReader?

时间:2010-04-16 20:41:22

标签: c# sql dispose sqldatareader sqlconnection

我注意到This question,但我的问题更加具体。

使用

有什么好处
using (SqlConnection conn = new SqlConnection(conStr))
{
     using (SqlCommand command = new SqlCommand())
     {
        // dostuff
     } 
}

而不是

using (SqlConnection conn = new SqlConnection(conStr))
{
     SqlCommand command = new SqlCommand();
     // dostuff
}

显然,如果您计划使用相同的连接运行多个命令,那么这很重要,因为关闭SqlDataReader比关闭和重新打开连接更有效(调用conn.Close();conn.Open();也将释放连接)。

我看到很多人坚持认为未能关闭SqlDataReader意味着保留开放的连接资源,但是只有在你不关闭连接的情况下才会适用?

5 个答案:

答案 0 :(得分:16)

在我看来,这里有两条规则:

  1. 实现IDisposable的类应包含在using块中。
  2. 您不应该依赖类的IDisposable实现来忽略规则1.
  3. 也就是说,即使您知道处理连接对象负责处理其关联的命令对象,也不应该依赖此行为。

    顺便说一下,可以用更干净的方式使用块来嵌套:

    using (SqlConnection conn = new SqlConnection(conStr))
    using (SqlCommand command = new SqlCommand())
    {
        // dostuff
    }
    

    我会用

    SqlCommand command = conn.CreateCommand();
    

    而不是创建新的SqlCommand,然后将其与连接相关联。

答案 1 :(得分:5)

技术上不需要它;关闭SqlConnection应该销毁SqlDataReader正在使用的所有资源。反之亦然;如果您处置使用Dispose创建的SqlConnection,则无需SqlDataReader CommandBehavior.CloseConnection

实际上说,但是,当一个类实现IDisposable时,你应该{I}完成它。框架类的实现细节随时可能发生变化,除非文档特别概述了Dispose实例的必要条件,否则将来可能会出现一些未来的更改/更新你的代码有资源泄漏。

这真的没有额外的努力 - 所以只需将它包装在Dispose块中。

答案 2 :(得分:1)

在很多情况下可能没有必要,但出于某种原因这是最佳做法。没有理由让资源持续超出它们不再有用的程度。 using构造有助于确保这一点。

答案 3 :(得分:0)

这不仅仅是你现在释放资源而不是垃圾收集的问题吗?

答案 4 :(得分:0)

有区别。如果你在没有打开/关闭连接的情况下创建那些读者的 2 ,但在使用第二个之前没有丢弃第一个,那么你会发现一个冲突,说连接已经打开了阅读器。