Должен ли я закрыть () SQLConnection до его удаления?

102

В другом вопросе здесь об одноразовых объектах, следует ли мы называть 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();
}
Теги:
sqlconnection
using
sqlcommand

8 ответов

94
Лучший ответ

Поскольку у вас есть используемый блок, будет вызываться метод 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);
}
  • 1
    Is this._poolGroup = null; означает, что соединение не возвращается в пул соединений? так что у меня будет n-1 соединений?
19

Разборка 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()

  • 1
    @statenjason: не могли бы вы сказать, как вы используете преимущества дизассемблеров линии .net отражатель?
  • 3
    @odiseh просто скачайте .NET Reflector, запустите отражатель, и вы сможете открыть любую .net DLL (включая стандартную библиотеку). Он предоставляет вам древовидную структуру, аналогичную объектному браузеру Visual Studio, однако вы можете щелкнуть правой кнопкой мыши по любому классу или методу и нажать «дизассемблировать», после чего он вернет вам источник в C # или VB, в зависимости от того, что вы выбрали в опции.
15

Ключевое слово 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);
}
  • 1
    +1 для ссылки MSDN - мне нравится рефлектор \ ILspy, как и следующий парень, но в документах я бы хотел найти ответы на свои вопросы.
3

Используя 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);
}
3

Нет, вызов Dispose() в SqlConnection также вызывает Close().

MSDN - SqlConnection.Dispose()

3

Нет, если для вас все равно задействован блок Dispose() для использования, поэтому нет необходимости вызывать Close().

  • 0
    Извините, я должен был сказать, что для большинства объектов, которые реализуют IDisposable и имеют метод Close (), вызов Close () в конечном итоге вызывает Dispose () в любом случае для вас.
  • 6
    Разве это не наоборот? Dispose() вызывает Close() , а не наоборот?
Показать ещё 1 комментарий
2

Нет, нет необходимости закрывать соединение перед вызовом Dispose.

Некоторые объекты (например, SQLConnections) могут быть повторно использованы afer для вызова Close, но не после вызова Dispose. Для других объектов вызов Close аналогичен вызову Dispose. (ManualResetEvent и потоки Я думаю, что так себя вести)

1

Нет, класс SqlConnection наследуется от IDisposable, и когда встречается конец использования (для объекта соединения), он автоматически вызывает Dispose в классе SqlConnection.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню