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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1808036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:02:39  来源:igfitidea点击:

Is SqlCommand.Dispose() required if associated SqlConnection will be disposed?

c#ado.netdisposesqlconnectionsqlcommand

提问by abatishchev

I usually use code like this:

我通常使用这样的代码:

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

Will my commandautomatically disposed? Or not and I have to wrap it into usingblock? Is it required to dispose SqlCommand?

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

采纳答案by RichardOD

Just do this:

只需这样做:

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

Not calling dispose on the command won't do anything too bad. However, calling Dispose on it will suppress the call to the finalizer, making calling dispose a performance enhancement.

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

回答by Adam Ralph

The safest policy is to always call Dispose()on an object if it implements IDisposable, either explicitly or via a using block. There may be cases where it is not required but calling it anyway should never cause problems (if the class is written correctly). Also, you never know when an implementation may change meaning that where the call was previously not required it is now definitely required.

最安全的策略是始终调用Dispose()一个对象,如果它IDisposable显式地或通过 using 块实现了 。可能存在不需要它但无论如何调用它永远不会导致问题的情况(如果类编写正确)。此外,您永远不知道何时实现可能会发生变化,这意味着以前不需要调用的地方现在绝对需要。

In the example you've given, you can add an extra inner using block for the command, as well as maintaining the outer using block for the connection.

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

回答by Quibblesome

You can find out this kind of stuff using Reflectoror dotPeek or https://referencesource.microsoft.com/.

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

I had a small dig (I would suggest that you dig yourself though to be fully sure of the rest of this though as I didn't try that hard) and it looks like when you kill a connection there is no disposal of any children associated with that connection. Furthermore it doesn't actually look like the disposal of a command actually does that much. It will set a field to null, detach itself from a container (this may prevent a managed memory leak) and raise an event (this might be important but I can't see who is listening to this event).

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

Either way it's good practice to use this stuff in a using block or to ensure you dispose of it using a dispose pattern in the object that holds the connection (if you intend to hold onto the command for a while).

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

回答by Lucero

Yes, you should, even if it the implementation is currently not doing much, you don't know how it is going to be changed in the future (newer framework versions for instance). In general, you should dispose all objects which implement IDisposableto be on the safe side.

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

However, if the operation is deferred and you don't control the full scope (for instance when working asynchroneously, or when returning an SqlDataReaderor so), you can set the CommandBehaviorto CloseConnectionso that as soon as the reader is done, the connection is properly closed/disposed for you.

但是,如果操作被延迟并且您没有控制整个范围(例如在异步工作时,或者在返回SqlDataReader左右时),您可以设置为CommandBehaviorCloseConnection以便读取器完成后,连接正确为您关闭/处置。

回答by Edward Brey

In practice, you can skip Dispose. It doesn't free any resources. It doesn't even suppress finalization since the SQLCommand constructor does that.

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

In theory, Microsoft could change the implementation to hold an unmanaged resource, but I would hope they'd come out with an API that gets rid of the Componentbase class long before they'd do that.

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

回答by Tahir Alvi

In my opinion, calling Disposefor both SqlConnectionand SqlCommandis good practice, use below code

在我看来,要求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();
}