Не вызывать SqlConnection.Close () в Windows Forms - почему иногда это работает - PullRequest
3 голосов
/ 21 июля 2011

Мой друг держал приложение ASP.NET 2.0 дома, пока он не переехал, и я предложил разместить его на моем собственном сервере Win7 / IIS7 / SQLE2008r2.

Когда я помещал код на моемсервер, после нескольких запросов я получаю эту ошибку:

Истекло время ожидания.Время ожидания истекло до получения соединения из пула.Это могло произойти из-за того, что все пулы подключений использовались и был достигнут максимальный размер пула.

Сначала я поднял максимальный размер пула, чтобы временно «исправить» проблему.Затем я внимательно посмотрел на его код.Оказалось, что он никогда не звонил SqlConnection.Close().Поэтому я добавил закрытие и удалил максимальный размер пула из всех строк подключения, и проблема была решена.

Я спросил его, как он решил проблему, и как он каким-то образом увеличил максимальный размер пула по умолчанию в своемпо умолчанию сервер web.config или что-то.Он ответил "Сборка мусора .NET".Поэтому он полагался на сборку мусора для закрытия соединений с базой данных и на работающий сервер.Но по моему это не так.

Кто-нибудь может объяснить, почему?Он в отпуске, поэтому я не хочу беспокоить его, спрашивая у него подробности о версиях и т. Д., Но я предполагаю, что он работал под управлением Win2k8.

Ответы [ 3 ]

4 голосов
/ 21 июля 2011

У Джеффа Этвуда есть замечательная статья об этой самой вещи, я очень рекомендую это прочитать.

Полагаться на сборку мусора .NET для закрытия SQL-соединений - нет-нет. SqlConnection.Close(), также как и Dispose(), всегда следует вызывать, но, по крайней мере, Close(). Обратите внимание, что ключевое слово using позаботится об автоматическом удалении объектов для вас (пример).

Безответственно и глупо полагаться на ГК во всем. Это все равно что игнорировать всю память и говорить: «О, когда у пользователя заканчивается ОЗУ, он может просто перезапустить!: D».

В ореховой оболочке код, не работающий на новом сайте развертывания, НЕ является вашей ошибкой. В данном случае это кодеры для безответственной обработки SQLConnection.

2 голосов
/ 21 июля 2011

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

Если вы оставите параметры соединения для очистки сборщика мусора, вы не сможете контролировать, когда это произойдет.случается.Сборщик мусора в конечном итоге закроет их, но когда это произойдет, это зависит от множества факторов, например, от того, сколько имеется доступной памяти и сколько памяти используется.Эти факторы будут отличаться от одного сервера к другому, но они могут также меняться со временем, поэтому вы даже не можете рассчитывать на сборщик мусора, который всегда будет работать одинаково даже на одном и том же сервере.

Реагируют разные базы данныхпо-разному иметь много незакрытых соединений.Например, база данных Access крайне чувствительна к этому, не допуская более 64 подключений.

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

0 голосов
/ 21 июля 2011

Совершенно нормально оставить его сборщику мусора, если скорость сборки мусора превышает скорость, с которой создаются новые соединения.Но я никогда не видел, чтобы кто-нибудь использовал ASP.NET таким образом, чтобы это могло произойти.

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

...