如果您已经关闭了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
意味着保留开放的连接资源,但这不仅适用于您不关闭连接吗?
在我看来,这里有两条规则:
- 实现IDisposable的类应该包含在
using
块中。 - 您不应该依赖类的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
构造有助于确保这一点。
是不是只是你现在释放资源与垃圾收集后来释放它?
有区别。 如果您在没有打开/关闭连接的情况下创建了其中两个读取器,但在使用第二个读取器之前没有丢弃第一个读取器,则会发生冲突,说连接已经与打开的读取器相关联。