C# 如果要处理关联的SqlConnection,是否需要SqlCommand.Dispose()?
我通常使用如下代码:C# 如果要处理关联的SqlConnection,是否需要SqlCommand.Dispose()?,c#,ado.net,dispose,sqlconnection,sqlcommand,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()
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
{
var command = connection.CreateCommand();
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
我的
命令是否会自动处理?或者不,我必须使用
块将其包装成?是否需要disposeSqlCommand
?最安全的策略是,如果对象显式或通过使用块实现了IDisposable
,则始终对其调用dispose()
。在某些情况下,它可能不是必需的,但无论如何调用它都不会导致问题(如果类编写正确)。此外,您永远不知道实现何时会发生变化,这意味着以前不需要调用的地方现在肯定需要调用
在您给出的示例中,您可以为命令添加额外的内部USE块,并为连接维护外部USE块。只需执行以下操作:
using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using(var command = connection.CreateCommand())
{
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
不在命令上调用dispose不会做任何坏事。但是,在它上调用Dispose将使调用Dispose成为一种性能增强。您可以使用或dotPeek或查找此类内容
我做了一个小小的挖掘(我建议你自己挖掘,以完全确定剩下的部分,因为我没有那么努力),看起来当你杀死一个连接时,没有处理任何与该连接相关的孩子。此外,它实际上看起来不像是一个命令的处理实际上做了那么多。它会将一个字段设置为null,将自身从容器中分离(这可能会防止托管内存泄漏)并引发一个事件(这可能很重要,但我看不到谁在侦听此事件)
无论哪种方式,最好在using块中使用这些东西,或者确保在保存连接的对象中使用dispose模式来处理它(如果您打算保留该命令一段时间)。是的,您应该这样做,即使实现目前做得不多,您不知道将来它将如何更改(例如更新的框架版本)。一般来说,您应该将实现IDisposable
的所有对象都放在安全的位置
但是,如果操作被延迟,并且您无法控制整个范围(例如异步工作时,或者返回SqlDataReader
等),则可以将CommandBehavior
设置为CloseConnection
,以便在读取器完成后,已为您正确关闭/释放连接。实际上,您可以跳过Dispose
。它不会释放任何资源。它甚至不抑制终结,因为
从理论上讲,微软可以改变实现来保存非托管资源,但我希望他们早在这么做之前就推出了一个API来摆脱组件
基类。在我看来,调用SqlConnection
和SqlCommand
都是很好的做法,使用下面的代码
using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
try{
using(var command = connection.CreateCommand())
{
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
}
catch(Exception ex){ //Log exception according to your own way
throw;
}
finally{
command.Dispose();
connection.Close();
connection.Dispose();
}
“不在命令上调用dispose不会做任何坏事。”没错,但不要习惯;这仅适用于SqlCommand
s。另一方面,例如,不处理SqlCeCommand
,将导致移动设备很快耗尽内存。(刚刚在那里,完成了…)Dispose
不会禁止终结,因为构造函数会这样做。@EdwardBrey哪个构造函数?@EdwardBrey它只在私有构造函数SqlConnection(SqlConnection connection)
中完成,该构造函数只能从方法调用。但是两个普通的公共构造函数都不调用GC.SuppressFinalize
,只有方法调用。所以我猜你错了。@Sergey对不起。我链接到了错误的构造函数。重要的是,它总是调用GC.SuppressFinalize
。是的,最安全的策略是始终处置一次性对象-尤其是如果您创建了它!例如,编写一个接受流的方法并在该方法中处理流不是一个好主意。另一个警告是,您不能总是通过using语句进行处理而不受惩罚。WCF代理是我所知道的唯一实用的例子。如果远程端出现问题,您得到一个异常,通道关闭并释放,然后抛出一个新的异常,替换原始异常,这可能是一个严重的问题。如果您使用了,则不需要这些代码:编译器将为您生成try/catch/Dispose()。@abatishchev,是的,您是对的,但捕获任何异常并正确记录它总是一个好的做法。