Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果要处理关联的SqlConnection,是否需要SqlCommand.Dispose()?_C#_Ado.net_Dispose_Sqlconnection_Sqlcommand - Fatal编程技术网

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();
}

我的
命令是否会自动处理?或者不,我必须使用
块将其包装成
?是否需要dispose
SqlCommand

最安全的策略是,如果对象显式或通过使用块实现了
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,是的,您是对的,但捕获任何异常并正确记录它总是一个好的做法。