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

我注意到了这个问题 ,但我的问题更加具体。

使用有什么好处

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意味着保留开放的连接资源,但这不仅适用于您不关闭连接吗?

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

  1. 实现IDisposable的类应该包含在using块中。
  2. 您不应该依赖类的IDisposable实现来忽略规则1。

也就是说,即使您知道处理连接对象负责处理其关联的命令对象,也不应该依赖此行为。

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

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

我会用

 SqlCommand command = conn.CreateCommand(); 

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

从技术上讲,它不是必需的; 关闭SqlConnection应该销毁SqlDataReader正在使用的任何资源。 反过来也是如此; 如果处置使用CommandBehavior.CloseConnection创建的SqlDataReader ,则不需要Dispose SqlConnection

实际上 ,当一个类实现IDisposable ,你应该在完成它时Dispose它。 框架类的实现细节随时可能发生变化,除非文档特别概述了不需要Dispose实例的情况,否则将来某些更改/更新将导致您的代码具有资源泄漏。

这真的没有额外的努力 – 所以只需将它包装在一个using块中。

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

是不是只是你现在释放资源与垃圾收集后来释放它?

有区别。 如果您在没有打开/关闭连接的情况下创建了其中两个读取器,但在使用第二个读取器之前没有丢弃第一个读取器,则会发生冲突,说连接已经与打开的读取器相关联。