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

时间:2009-11-27 10:47:22

标签: c# ado.net dispose sqlconnection sqlcommand

我通常使用这样的代码:

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

我的command会自动处理吗?或者不是,我必须将其包装到using块中?是否需要处置SqlCommand

6 个答案:

答案 0 :(得分:26)

这样做:

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

不在命令上调用dispose也不会做太糟糕的事情。然而,在supress the call to the finalizer上调用Dispose会使调用dispose成为一种性能增强。

答案 1 :(得分:11)

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

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

答案 2 :(得分:5)

是的,你应该,即使它的实现目前没有做太多,你也不知道将来会如何改变它(例如更新的框架版本)。通常,您应该将实现IDisposable的所有对象都置于安全的一边。

但是,如果操作延迟并且您不控制完整范围(例如,在异步工作时或返回SqlDataReader左右时),则可以将CommandBehavior设置为{ {1}}以便读者完成后,就可以为您正确关闭/处理连接。

答案 3 :(得分:3)

您可以使用Reflector或dotPeek或https://referencesource.microsoft.com/找到此类内容。

我进行了一次小挖掘(我建议你挖掘自己虽然完全确定其余的但是因为我没有那么努力)并且看起来当你杀死一个连接时没有处理任何与该连接相关的孩子。此外,它实际上看起来并不像命令的处理实际上那么多。它会将一个字段设置为null,从容器中分离(这可能会阻止托管内存泄漏)并引发一个事件(这可能很重要,但我看不到谁在听这个事件)。

无论哪种方式,最好在使用块中使用这些东西,或者确保使用保存连接的对象中的dispose模式处理它(如果您打算暂停命令一段时间)。

答案 4 :(得分:3)

实际上,您可以跳过Dispose。它不释放任何资源。它甚至不会抑制自SQLCommand constructor does that以来的最终确定。

理论上,微软可能会改变实现以保存非托管资源,但我希望他们能够在他们这么做之前很久就推出一个能够摆脱Component基类的API。 / p>

答案 5 :(得分:2)

我认为同时调用DisposeSqlConnection的{​​{1}}是很好的做法,请使用以下代码

SqlCommand