Требуется ли SqlCommand.Dispose (), если связанный SqlConnection будет удален? - PullRequest
25 голосов
/ 27 ноября 2009

Я обычно использую такой код:

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

Будут ли мои command автоматически выбрасываться? Или нет, и я должен обернуть его в using блок? Нужно ли утилизировать SqlCommand?

Ответы [ 6 ]

26 голосов
/ 27 ноября 2009

Просто сделайте это:

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

Не вызывая dispose по команде не будет ничего плохого. Однако вызов Dispose для него подавляет вызов для финализатора , что делает вызов dispose повышением производительности.

10 голосов
/ 27 ноября 2009

Самая безопасная политика - всегда вызывать Dispose() для объекта, если он реализует IDisposable, явно или через блок using. Могут быть случаи, когда это не требуется, но вызов в любом случае никогда не должен вызывать проблем (если класс написан правильно). Кроме того, вы никогда не знаете, когда реализация может измениться, а это означает, что там, где ранее вызов не требовался, теперь определенно требуется.

В приведенном вами примере вы можете добавить дополнительный внутренний блок использования для команды, а также сохранить внешний блок использования для соединения.

4 голосов
/ 27 ноября 2009

Да, вы должны, даже если реализация в настоящее время не делает много, вы не знаете, как это изменится в будущем (например, в новых версиях фреймворка). В общем, вы должны утилизировать все объекты, которые реализуют IDisposable, чтобы быть в безопасности.

Однако, если операция отложена и вы не управляете полной областью действия (например, при асинхронной работе или при возврате SqlDataReader или около того), вы можете установить CommandBehavior на CloseConnection, чтобы Как только считыватель завершит работу, соединение будет правильно закрыто для вас.

2 голосов
/ 17 октября 2015

На практике вы можете пропустить Dispose. Это не освобождает любые ресурсы. Он даже не подавляет завершение, так как конструктор SQLCommand делает это .

Теоретически Microsoft могла бы изменить реализацию для хранения неуправляемых ресурсов, но я надеюсь, что они выпустят API, который избавляется от базового класса Component задолго до того, как они это сделают.

2 голосов
/ 27 ноября 2009

Вы можете узнать такие вещи, используя Отражатель или dotPeek или https://referencesource.microsoft.com/.

У меня было небольшое копание (я бы посоветовал вам копать себя, хотя, чтобы быть полностью уверенным в остальном, хотя я и не старался), и похоже, что когда вы убиваете соединение, нет никакого избавления от любые дети, связанные с этой связью. Кроме того, на самом деле это не похоже на то, что избавление от команды действительно так много делает. Он установит в ноль поле, отсоединится от контейнера (это может предотвратить утечку управляемой памяти) и вызовет событие (это может быть важно, но я не вижу, кто слушает это событие).

В любом случае рекомендуется использовать этот материал в блоке using или убедиться, что вы избавляетесь от него с помощью шаблона dispose в объекте, который содержит соединение (если вы собираетесь удерживать команду некоторое время).

1 голос
/ 01 марта 2019

По моему мнению, звонить Dispose для 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...