Подтвердить что ты не робот

С# - закрытие лучших объектов Sql

Если у вас есть функция С# с Sqlaccess, обязательно закрыть все объекты/дескрипторы или все очистится автоматически после выхода из функции

Например:

void DoSqlStuff()
{
    SqlConnection sqlConn = new SqlConnection(...);
    SqlCommand cmd = new SqlCommand(...);
    SqlDataReader sqlData= null;

    sqlConn,Open();
    sqlData = cmd.ExecutReader();


    while(sqlData.Read())
    {
         ...
    }
}

Необязательно, рекомендуется или обязательно закрыть SqlConn и SqlData?

Спасибо.

4b9b3361

Ответ 1

Вы должны закрыть объект SqlConnection, как только закончите с ним. Если вы этого не сделаете, соединение останется открытым и не будет доступно для обработки других запросов.

Оператор using полезен для этого. Он вызовет Dispose() для объекта для вас:

using (SqlConnection cn = new SqlConnection(connectionString))
{   
    SqlCommand cm = new SqlCommand(commandString, cn)
    cn.Open();
    cm.ExecuteNonQuery();       
}

Ответ 2

Вам не нужно иметь отдельный оператор using для SqlDataReader (а также один оператор using для соединения), если вы не планируете выполнять другие операции с соединением после того, как SqlDataReader полностью прочитал набор строк.

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

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

Ответ 3

Вы должны закрыть все перед возвратом из функции. Открытые datareaders означают открытые курсоры в базе данных, что приводит к увеличению использования памяти. То же самое касается соединений с базой данных.

Неиспользуемые объекты не сразу освобождаются на С#, но только тогда, когда выполняется сбор мусора, который не является детерминированным.

Ответ 4

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

Ответ 5

Вызов Close на SQL-соединении фактически не закрывает его, а возвращает его в пул соединений, который будет использоваться повторно, и улучшая производительность.

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

Ответ 6

Явное распоряжение в заявлении finally - это еще один подход, хотя утверждение using является гораздо лучшим решением. Он создает немного больше кода, но демонстрирует цель...

SqlConnection conn = null;
try
{
    //create connection

    SqlCommand cmd = null;
    try
    {
        //create command

        SqlDataReader reader = null;
        try 
        {
            //create reader
        }
        finally
        {
            reader.Dispose();
        }
    }
    finally
    {
        cmd.Dispose();
    }
}
finally 
{
    conn.Dispose();
}

Ответ 7

Будьте осторожны с абсолютами здесь. Многое зависит от того, что вы делаете и где могут быть неэффективны. На веб-странице, где каждый пользователь имеет отдельный контекст безопасности, у вас может не быть другого выбора, кроме как установить новое соединение SQL с новыми учетными данными безопасности с каждым ударом страницы. Ясно, если вы можете использовать пул соединений SQL с общим контекстом безопасности и позволить веб-странице фильтровать результаты, но, возможно, вы не можете.

В ранних версиях SQL Server, т.е. (v6.5 или менее), аутентификация входа выполнялась SQL Server. Кроме того, SQL был сильно ограничен памятью подключения и количеством активных подключений, которые он мог бы обрабатывать. Поэтому было прекрасной идеей отказаться от вашей связи, когда она не используется. Post v6.5, большинство пользователей используют аутентификацию Windows для входа в SQL. Это вызывает множество сетевых вызовов между серверами и некоторую задержку. Kerberos Security еще более болтлива, поэтому установить соединение с SQL стоит дорого. По этой причине вам нужно найти баланс между удерживанием соединения открытым для жизни вашего приложения WinForms vs Открытие и закрытие его в каждом вызове метода.

В качестве приблизительного руководства, если вы думаете, что ваше приложение захочет поговорить с SQL в следующем, скажем, 30 секунд. Держите установленное соединение открытым. Если они минимизировали ваше приложение, не касались его в течение периода ожидания или у вас все данные в ОЗУ, и они вряд ли нуждаются в чем-либо больше от системы SQL. Закройте соединение.

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

Если вы также не пишете код на базе сервера, небольшое количество неэффективности памяти может даже не заметить. Но 2-10 000 клиентов, которые плохо используют ваши серверы безопасности и данных, скорее всего, приведут ваш центр данных к коленям.

Ответ 8

Любой класс, обрабатывающий SQL-материалы, такие как Connections, должен реализовывать интерфейс IDisposable, как указано в инструкциях Microsoft.NET по кодированию.

Таким образом, вероятно, вы должны закрыть и удалить свое соединение в методе Dispose.