В другом вопросе здесь об одноразовых объектах, следует ли мы называть Close() до конца используемого блока?
using (SqlConnection connection = new SqlConnection())
using (SqlCommand command = new SqlCommand())
{
command.CommandText = "INSERT INTO YourMom (Amount) VALUES (1)";
command.CommandType = System.Data.CommandType.Text;
connection.Open();
command.ExecuteNonQuery();
// Is this call necessary?
connection.Close();
}
Поскольку у вас есть используемый блок, будет вызываться метод Dispose SQLCommand и он закроет соединение:
// System.Data.SqlClient.SqlConnection.Dispose disassemble
protected override void Dispose(bool disposing)
{
if (disposing)
{
this._userConnectionOptions = null;
this._poolGroup = null;
this.Close();
}
this.DisposeMe(disposing);
base.Dispose(disposing);
}
Разборка SqlConnection с помощью .NET Reflector:
protected override void Dispose(bool disposing)
{
if (disposing)
{
this._userConnectionOptions = null;
this._poolGroup = null;
this.Close();
}
this.DisposeMe(disposing);
base.Dispose(disposing);
}
Он вызывает Close() внутри Dispose()
Ключевое слово using будет правильно закрывать соединение, поэтому дополнительный вызов Close не требуется.
Из статьи MSDN в Пул соединений SQL Server:
"Мы настоятельно рекомендуем вам всегда закрыть соединение, когда вы закончил использовать его так, чтобы соединение будет возвращено бассейн. Вы можете сделать это, используя Закрыть или удалить методы Объект подключения или , открыв все соединения внутри оператора usingв С#"
Фактическая реализация SqlConnection.Dispose с использованием .NET Reflector выглядит следующим образом:
// System.Data.SqlClient.SqlConnection.Dispose disassemble
protected override void Dispose(bool disposing)
{
if (disposing)
{
this._userConnectionOptions = null;
this._poolGroup = null;
this.Close();
}
this.DisposeMe(disposing);
base.Dispose(disposing);
}
Используя Reflector, вы можете видеть, что метод Dispose
SqlConnection
действительно вызывает вызов Close()
;
protected override void Dispose(bool disposing)
{
if (disposing)
{
this._userConnectionOptions = null;
this._poolGroup = null;
this.Close();
}
this.DisposeMe(disposing);
base.Dispose(disposing);
}
Нет, вызов Dispose() в SqlConnection также вызывает Close().
Нет, если для вас все равно задействован блок Dispose()
для использования, поэтому нет необходимости вызывать Close()
.
Dispose()
вызывает Close()
, а не наоборот?
Нет, нет необходимости закрывать соединение перед вызовом Dispose.
Некоторые объекты (например, SQLConnections) могут быть повторно использованы afer для вызова Close, но не после вызова Dispose. Для других объектов вызов Close аналогичен вызову Dispose. (ManualResetEvent и потоки Я думаю, что так себя вести)
Нет, класс SqlConnection наследуется от IDisposable, и когда встречается конец использования (для объекта соединения), он автоматически вызывает Dispose в классе SqlConnection.