Закрытие нулевого соединения SQL - PullRequest
0 голосов
/ 23 сентября 2019

У меня есть вопрос о закрытии открытого соединения с базой данных в C #.Допустим, мы отказываемся от метода «using» и используем блок try / catch / finally, чтобы открыть и закрыть соединение.

try 
{
    connection = new SqlConnection();
    connection.Open();
}
catch (Exception ex)
{
    // Do whatever you need with exception
}
finally
{
  1.connection.Dispose();
  2.if (connection != null)
    {
        connection.Dispose();
    }
}

Мой вопрос заключается в том, что именно происходит, если в этом сегменте кода происходит только 1),Перед удалением (закрытием) соединение всегда должно проверяться на нулевое значение, но что, если это не так, и мы пытаемся закрыть объект соединения с нулевым значением?(Меня интересует, что происходит с открытым соединением, может ли это привести к утечке)

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Не вызывайте Dispose() напрямую, пусть это делает предложение using.

Если вы хотите проверить, является ли null скрупулезным, вы можете переписать свой код следующим образом, добавивСтрока подключения:

using ( var connection = new SqlConnection(strConnection) )
  if (connection != null)
    try 
    {
      connection.Open();
      // ...
    }
    catch (Exception ex)
    {
      // ...
    }
    finally
    {
      connection.Close();
    }
0 голосов
/ 23 сентября 2019

В вопросе, если connection.Dispose() вызывается для соединения null без проверки, вы вызываете новое исключение, которое не было обработано, и все, что с этим связано.Кроме того, если это было сделано из-за того, что переменная connection была установлена ​​на null до того, как блок finally не был закрыт, возможно утечка этого открытого соединения ... хотя и какНа практике редко можно увидеть код в дикой природе, который знает, что нужно использовать finally, но также хочет установить соединение на null.

Предоставление отсутствия using (что подозрительно, нокак бы то ни было), я предпочитаю этот шаблон:

finally
{
    if (connection is IDisposable) connection.Dispose();
}

Этот по-прежнему защищает от null значений * в connection объекте и является более близкой имитацией того, что usingшаблон уже делал за кулисами.

Обратите внимание, однако, что вы все еще упускаете одну важную особенность блока using, которая является защитой от чего-то, присваивающего null вашей переменной до его закрытия.Блоки using также защищают ваше соединение в отдельной (скрытой) переменной, поэтому вы уверены, что у вас все еще есть действительная ссылка в конце блока (это ново в C # 8).

* (Для полноты автор этого связанного твита является лидером в команде компиляторов C #, поэтому он должен знать, и он не иронизирует).

...