В чем разница между connection.Close() и connection.Dispose() в C#?
Что проверяют
Понимаете ли вы, что у SqlConnection за объектом стоит пул соединений, и не путаете закрытие объекта с разрывом физического соединения. Следом почти всегда спрашивают, как работает пул в ADO.NET и почему соединение не держат открытым в поле класса.
Как отвечать
Для SqlConnection (и любого DbConnection) оба метода делают почти одно и то же: Dispose() внутри вызывает Close(). Разница в контракте:
Close(): закрывает логическое соединение, физическое уходит обратно в пул. Объект остаётся рабочим, его можно снова открыть черезOpen();Dispose(): реализацияIDisposable, финальная точка жизни объекта. Закрывает соединение так же, какClose(), и дополнительно сбрасываетConnectionString, поэтому повторныйOpen()упадёт сInvalidOperationException;- пул: при
Pooling=true(по умолчанию) иClose(), иDispose()возвращают физическое соединение в пул. Пул заводится на каждую уникальную строку подключения, лимит по умолчаниюMax Pool Size=100.
Практическое правило: открывать соединение как можно позже, закрывать как можно раньше и оборачивать в using. С C# 8 удобнее using var connection = new SqlConnection(cs);, а в асинхронном коде await using, потому что DbConnection реализует IAsyncDisposable. Хорошо добавить, что актуальный провайдер это Microsoft.Data.SqlClient, а System.Data.SqlClient объявлен устаревшим.
Где спотыкаются
Говорят, что Dispose() уничтожает физическое соединение и выключает пул. Это неправда: при включённом пуле соединение вернётся туда в обоих случаях, а открывать новое на каждый запрос дёшево именно благодаря пулу.
Держат одно открытое соединение в поле или синглтоне «для скорости». Итог: гонки при работе из нескольких потоков, ошибки про уже открытый DataReader и соединения, которые не возвращаются в пул.
Забывают про остальные объекты: SqlCommand и SqlDataReader тоже нужно освобождать, а незакрытый ридер держит соединение занятым. При исключении без using или finally соединение утекает, и под нагрузкой пул упирается в лимит, а новые запросы падают по таймауту ожидания.