30

我通常使用这样的代码:

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

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

4

6 回答 6

32

只需这样做:

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

不在命令上调用 dispose 不会做任何坏事。但是,对其调用 Dispose 将抑制对 finalizer 的调用,从而使调用 dispose 提高性能。

于 2009-11-27T10:51:34.147 回答
15

Dispose()最安全的策略是在对象实现时始终调用它IDisposable,无论是显式地还是通过 using 块。在某些情况下,它不是必需的,但无论如何调用它都不会导致问题(如果类编写正确)。此外,您永远不知道什么时候实现可能会改变,这意味着以前不需要调用的地方现在肯定需要调用。

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

于 2009-11-27T10:51:08.127 回答
6

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

但是,如果操作被延迟并且您无法控制整个范围(例如,在异步工作时,或在返回一个左右SqlDataReader时),您可以将为您关闭/处置。CommandBehaviorCloseConnection

于 2009-11-27T12:15:12.650 回答
4

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

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

于 2015-10-16T21:30:20.067 回答
3

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

我做了一个小挖掘(我建议你自己挖掘一下,以完全确定剩下的部分,因为我没有那么努力),看起来当你杀死一个连接时,没有任何相关的孩子被处理与那个联系。此外,它实际上看起来不像一个命令的处置实际上做了那么多。它将一个字段设置为空,将自己与容器分离(这可能会防止托管内存泄漏)并引发一个事件(这可能很重要,但我看不到谁在听这个事件)。

无论哪种方式,最好在 using 块中使用这些东西,或者确保使用持有连接的对象中的 dispose 模式来处置它(如果您打算暂时持有该命令)。

于 2009-11-27T12:03:03.077 回答
0

在我看来,两者Dispose兼而有之是一种很好的做法,请使用以下代码SqlConnectionSqlCommand

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();
}
于 2019-03-01T12:14:55.540 回答