Вызывающее соединение.Закрыть / утилизировать в финализаторе

#.net #ado.net #garbage-collection #connection #database-connection

#.net #ado.net #сборка мусора #соединение #database-connection

Вопрос:

Я всегда вызывал Connection.Закрыть в блоке finally, однако сегодня я узнал, что вы не должны этого делать:

Не вызывайте Close или Dispose для соединения, DataReader или любого другого управляемого объекта в методе Finalize вашего класса. В финализаторе вы должны освобождать только неуправляемые ресурсы, которыми напрямую владеет ваш класс. Если ваш класс не владеет никакими неуправляемыми ресурсами, не включайте метод Finalize в определение вашего класса

Итак, при понимании того, что удаление объекта SqlCommand не приводит к удалению или закрытию назначенного ему объекта connection, будет ли следующий (упрощенный код ниже) одновременно удалять команду и объект connection? и действительно ли мне нужно вызывать Connection.Утилизировать, если я уверен, что всегда вызываю Connection.Закрыть?

 Using cmd As New NpgsqlCommand(String.Empty, new connection())
    cmd.CommandText = "some sql command here"
    sqlCmd.Connection.Open()
    ...create and fill data table
    sqlCmd.Connection.Close()
End Using
  

Комментарии:

1. Наконец, блок и финализатор — это две совершенно разные конструкции с совершенно разным назначением.

2. Спасибо всем, забеспокоился и запутался!

Ответ №1:

Нет, вам не нужно вызывать Close явно, если вы используете Using блок. Вот как я бы это написал:

 Using conn As New SqlConnection("SOME CONNECTION STRING")
    Using cmd = conn.CreateCommand()
        conn.Open()
        cmd.CommandText = "some sql command here"

        ' ... create and fill data table
    End Using
End Using
  

Также вызов Close не закрывает соединение. ADO.NET использует пул соединений, поэтому вызов Close просто возвращает соединение в пул. Это физически не закрывает соединение.

Комментарии:

1. Я знал, что вы можете вложить using, но я подумал, не могли бы вы их тоже объединить и получить тот же эффект?

Ответ №2:

То, что вы делаете, прекрасно. Финализаторы отличаются от блоков finally. Проверьте http://www.switchonthecode.com/tutorials/csharp-tutorial-object-finalizers для обсуждения того, что такое финализаторы.