如果关联的SqlConnection将被处理,是否需要SqlCommand.Dispose()?

aba*_*hev 26 c# ado.net dispose sqlcommand sqlconnection

我通常使用这样的代码:

using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
{
   var command = connection.CreateCommand();
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)

我会command自动处理吗?或者不是,我必须把它包装成using块?是否需要处理SqlCommand?

Ric*_*dOD 27

这样做:

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using(var command = connection.CreateCommand())
{
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)

不在命令上调用dispose也不会做任何太糟糕的事情.但是,在它上面调用Dispose会压缩对终结器的调用,从而使调用dispose成为一种性能增强.

  • "不要在命令上调用dispose也不会做太糟糕的事情." 没错,但不要习惯它; 它只适用于`SqlCommand`.另一方面,没有处理`SqlCeCommand`,例如*会导致你的移动设备内存不足.(就在那里,做到了......) (16认同)
  • "Dispose"不会抑制最终化,因为构造函数会这样做. (5认同)

Ada*_*lph 10

最安全的策略是,Dispose()如果对象IDisposable显式或通过using块实现,则始终调用它.可能存在不需要它但无论如何调用它应该永远不会引起问题(如果类正确写入)的情况.此外,您永远不知道实现何时可能会改变意味着以前不需要呼叫的地方现在肯定是必需的.

在您给出的示例中,您可以为命令添加额外的内部使用块,以及为连接维护外部使用块.

  • 是的,最安全的政策是始终处理一次性物品 - 特别是如果你*创造了它!例如,编写一个接受流的方法并将流配置在该方法中并不是一个好主意.另一个警告是,你不能总是通过使用声明处置而不受惩罚.WCF代理是我所知道的唯一实用示例.如果远程端出现问题并且您获得异常,则通道关闭并且Dispose然后抛出新的异常,替换原始异常,这可能是一个严重的问题. (2认同)

Luc*_*ero 6

是的,您应该,即使它实现当前没有做太多,您也不知道将来如何更改它(例如更新的框架版本).通常,您应该将所有实现的对象都IDisposable放在安全的一侧.

但是,如果操作延迟并且您没有控制整个范围(例如,当异步工作或返回一个SqlDataReader左右时),您可以设置为CommandBehavior,CloseConnection以便在读取器完成后,连接正确关闭/处置你.


Edw*_*rey 6

在实践中,您可以跳过Dispose。它不会释放任何资源。它甚至不会抑制终结,因为SQLCommand 构造函数会这样做。

Component从理论上讲,微软可以更改实现以保存非托管资源,但我希望他们早在这样做之前就推出了一个可以摆脱基类的 API 。