Почему бы не закрыть соединение с базой данных в блоке finally - PullRequest
4 голосов
/ 26 июня 2009

Major Edit: Я неправильно прочитал статью! Комментарий касался метода finalize класса, а не блока finally :). Извинения.

Я только что прочитал, что вы не должны закрывать или размещать соединение с базой данных в блоке finally, но в статье не объясняется, почему. Кажется, я не могу найти четкого объяснения того, почему вы не хотите этого делать.

Вот статья

Ответы [ 6 ]

13 голосов
/ 26 июня 2009

Если вы посмотрите вокруг, закрытие соединения в блоке finally является одним из рекомендуемых способов сделать это. Вероятно, в статье, которую вы просматривали, рекомендовано использовать оператор using для кода, который использовал соединение.

using (SqlConnection connection = new SqlConnection(connectionString))
{
    SqlCommand command = connection.CreateCommand();

    command.CommandText = "select * from someTable";

    // Execute the query here...put it in a datatable/dataset
}

Оператор 'using' гарантирует, что объект Connection будет удален сразу после того, как он потребуется, вместо того, чтобы ждать, пока сборщик мусора избавится от него.

4 голосов
/ 26 июня 2009

Я должен не согласиться с тем, что вы не должны закрывать или удалять соединение с базой данных в блоке finally.

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

Закрытие соединения с базой данных - пример того, почему использовать оператор finally, ИМХО. Конечно, оператор using - мой предпочтительный метод, который, возможно, и был тем, к чему стремился оригинальный автор.

Править в мажор Править: Это имеет смысл сейчас. Вы не хотели бы оставлять закрытие соединения с базой данных вплоть до сборщика мусора.

3 голосов
/ 26 июня 2009

Без оригинальной статьи я не могу говорить за автора. Однако, в зависимости от того, как вы реализовали создание экземпляра и открытие соединения относительно вашего блока try / catch / finally, вам может потребоваться выполнить дополнительную проверку, прежде чем просто вызывать close. Например, убедитесь, что соединение не нулевое и не закрыто.

РЕДАКТИРОВАТЬ: в статье говорится, что не следует удалять объект подключения в вашем методе Finalize, не закрывать его в блоке finally. Фактически, в вышеприведенном параграфе говорится, что вы всегда должны закрывать соединение после его использования, поэтому оно возвращается в пул соединений.

"ВНИМАНИЕ! Рекомендуется всегда закрывать Соединение после завершения его использования, чтобы соединение было возвращено в пул. Это можно сделать с помощью методов Close или Dispose объекта Connection. Соединения, которые явно не закрыты, могут не быть добавлены или возвращены в пул. Например, соединение, вышедшее из области действия, но не закрытое явно, будет возвращено в пул соединений только в том случае, если достигнут максимальный размер пула и соединение все еще в силе.

Примечание Не вызывайте Close или Dispose для Connection, DataReader или любого другого управляемого объекта в методе Finalize вашего класса. В финализаторе освобождайте только неуправляемые ресурсы, которыми непосредственно владеет ваш класс. Если ваш класс не владеет какими-либо неуправляемыми ресурсами, не включайте метод Finalize в определение класса. Для получения дополнительной информации "

http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.71).aspx?ppud=4

2 голосов
/ 26 июня 2009

Из того, что я вижу в статье, он советует не вызывать Dispose или Close в Finalizer класса, а не делать это в finally-блоке , что довольно другое дело.

2 голосов
/ 26 июня 2009

Немного Googling поднимает довольно много страниц, которые держат противоположное мнение . Использование блока "finally" кажется хорошим способом убедиться, что соединение всегда закрыто правильно, хотя, как говорили другие, мне было бы интересно посмотреть оригинальную статью, в которой говорилось, что это не очень хорошая идея.

0 голосов
/ 26 июня 2009

Метод Close переводит объект подключения в состояние, из которого он может быть повторно открыт. Метод Dispose переводит его в состояние, из которого он не может быть повторно открыт (закрывая его первым, если он открыт).

Если вы создаете экземпляр соединения, открываете его, используете его, а затем выбрасываете его (обычная схема использования), тогда блок using - лучший и самый простой способ сделать это.

Очевидно, что если вы делаете что-то более сложное с несколькими вызовами Open и Close, то утилизация этого ключа приведет к созданию гаечного ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...