如果关联的SqlConnection将被处理,是否需要SqlCommand.Dispose()?
-
05-07-2019 - |
题
我通常使用这样的代码:
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
{
var command = connection.CreateCommand();
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
我的命令
会自动处理吗?或者不是,我必须使用块将其包装到中?是否需要处理
SqlCommand
?
解决方案
这样做:
using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using(var command = connection.CreateCommand())
{
command.CommandText = "...";
connection.Open();
command.ExecuteNonQuery();
}
不在命令上调用dispose也不会做太糟糕的事情。但是,在其上调用Dispose将拒绝调用终结器,使呼叫处理性能增强。
其他提示
最安全的策略是,如果对象显式地或通过using块实现 IDisposable
,则始终在对象上调用 Dispose()
。可能存在不需要它但无论如何调用它应该永远不会引起问题(如果类正确写入)的情况。此外,您永远不知道实施何时可能会改变意味着以前不需要呼叫的地方现在肯定是必需的。
在您给出的示例中,您可以为命令添加额外的内部使用块,以及为连接维护外部使用块。
是的,你应该,即使它的实现目前没有做太多,你也不知道将来会如何改变它(例如更新的框架版本)。通常,您应该将实现 IDisposable
的所有对象都置于安全的一边。
但是,如果操作延迟并且您不控制整个范围(例如,当异步工作时,或者返回 SqlDataReader
时),则可以设置 CommandBehavior
到 CloseConnection
,这样一旦读者完成,就会为你正确关闭/处理连接。
您可以使用 Reflector 或dotPeek或<找到这类内容a href =“https://referencesource.microsoft.com/”rel =“nofollow noreferrer”> https://referencesource.microsoft.com/ 。
我进行了一次小挖掘(我建议你挖掘自己虽然完全确定其余的但是因为我没有那么努力)并且看起来当你杀死一个连接时没有处理任何与该连接相关的孩子。此外,它实际上看起来并不像命令的处理实际上那么多。它会将一个字段设置为null,从容器中分离(这可能会阻止托管内存泄漏)并引发一个事件(这可能很重要,但我看不到谁在听这个事件)。
无论哪种方式,最好在使用块中使用这些东西,或者确保使用保存连接的对象中的dispose模式处理它(如果您打算暂停命令一段时间)。
实际上,您可以跳过 Dispose
。它不释放任何资源。它甚至不能抑制最终化,因为 SQLCommand构造函数执行此操作。
从理论上讲,微软可能会改变实现以保存非托管资源,但我希望他们能够在他们做之前就推出一个能够摆脱 Component
基类的API。这一点。
在我看来,为 SqlConnection
和 SqlCommand
调用 Dispose
是一种很好的做法,请使用下面的代码
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();
}