Требуется ли SqlCommand.Dispose (), если связанный SqlConnection будет удален?

StackOverflow https://stackoverflow.com/questions/1808036

Вопрос

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

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 для него прервет вызов финализатора , что делает вызов распоряжаться повышением производительности.

Другие советы

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

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

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

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

Подобные вещи вы можете узнать, используя Reflector или dotPeek или < a href = "https://referencesource.microsoft.com/" rel = "nofollow noreferrer"> https://referencesource.microsoft.com/ .

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

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

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

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

По моему мнению, вызов 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();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top