2009-06-19 2 views
7

Раньше сегодня я нашел ошибку в одном из наших проектов - есть соединение с базой данных, которая никогда не закрывается, я имею в виду, что метод Close() никогда не вызывается. Однако, когда я закрываю приложение, соединение закрывается (многократно проверяется в студии управления sql). Зачем?Что происходит с закрытым подключением к базе данных?

ответ

4

Соединение закрывается при выходе приложения. Читайте дальше: SqlConnection's Finalize. Из документации MSDN для Object.Finalize:

«Во время остановки домена приложения Finalize автоматически вызывается объектам, которые не освобождаются от завершения, даже те, которые все еще доступны».

+0

«Если SqlConnection выходит за пределы области видимости, он не будет закрыт, поэтому вы должны явно закрыть соединение, вызвав Close или Dispose». - это также из msdn, не означает ли это, что соединение не может быть закрыто, если вы не вызываете Close()? – agnieszka

+0

В основном вы можете делать Close, Dispose или use() {}, как и должно быть. Когда приложение закроется, соединения также будут закрыты по той причине, о которой я сказал в своем ответе. – RichardOD

+0

Также, если GC в любое время решит завершить соединения, то они также будут закрыты. – RichardOD

1

SQL-соединения дороги для создания, и ADO.NET использует технику, называемую пулом соединений, которая позволяет их повторно использовать.

Цитата MSDN:

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

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

+1

Фактически из-за пула соединений SQL-соединение никогда не закрывается - оно просто возвращается в пул, чтобы повторно использовать его при вызове Close. Он будет закрыт, когда домен приложения будет уничтожен, когда вы выйдете из приложения. Поэтому, если вы никогда не вызываете Close, соединение не будет использоваться повторно, и как только пул будет исчерпан, вы получите исключение. –

+0

@ darin- никогда не закрывается неправильно. После определенного количества бездействия соединение будет закрыто, но это просто придирание. – RichardOD

+1

@ RichardOD, я бы не сказал, что это ничто. На самом деле я этого не знал. Большое спасибо за эту точность. –

1

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

Когда приложение выходит из строя, возможно, финализатор не будет запущен, оставив соединение открытым после срока службы приложения.

2

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

// this using block will auto close & dispose your connection... 
using (var conn = new SqlConnection(...)) 
{ 
    conn.Open(); 
    // database code here with no explicit close 

} 

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

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

+0

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

+0

Не было никакого блока, я знаю о них. – agnieszka

+0

, и это не ответ на вопрос – agnieszka

Смежные вопросы