VB.NET - должен ли метод Finalize быть добавлен при реализации IDisposable? - PullRequest
5 голосов
/ 22 сентября 2008

В Visual Studio при вводе строки "Implements IDisposable" в среде IDE автоматически добавляется:

  • a disposedValue переменная-член
  • a Sub Dispose() Implements IDisposable.Dispose
  • a Sub Dispose(ByVal disposing As Boolean)

Dispose() следует оставить в покое, а код очистки должен быть введен в Dispose(disposing).

Однако Dispose Finalize Pattern говорит, что вы также должны переопределить Sub Finalize() для вызова Dispose(False). Почему IDE также не добавляет это? Должен ли я добавить это сам, или это как-то неявно называется?

РЕДАКТИРОВАТЬ: Есть идеи, почему IDE автоматически добавляет 80% необходимого материала, но не использует метод Finalize? Разве весь смысл такого рода функций в том, чтобы помочь вам не забыть эти вещи?

РЕДАКТИРОВАТЬ 2: Спасибо всем за ваши прекрасные ответы, теперь это имеет смысл!

Ответы [ 4 ]

11 голосов
/ 22 сентября 2008

Если вы на самом деле держите неуправляемые ресурсы, которые не будут автоматически очищаться сборщиком мусора и очищать их в вашем Dispose (), тогда да, вы должны сделать то же самое в Finalize ().

Если вы внедряете IDisposable по какой-либо другой причине, реализация Finalize () не требуется.

Основной вопрос заключается в следующем: если Dispose () не был вызван и ваш мусор собрал объект, произойдет ли утечка памяти? Если да, внедрите Finalize. Если нет, вам не нужно. Также избегайте реализации Finalize «только потому, что это безопаснее». Для объектов с пользовательскими финализаторами потенциально могут потребоваться два прохода GC, чтобы освободить их - один, чтобы поместить их в очередь ожидающих финализаторов, и второй проход, чтобы фактически освободить их память.

3 голосов
/ 22 сентября 2008

Нет, вам не нужно завершать, если у вас нет неуправляемых ресурсов для очистки.

В большинстве случаев класс является одноразовым, потому что он хранит ссылки на другие управляемые объекты IDisposable. В этом случае метод Finalize не является необходимым или желательным.

2 голосов
/ 12 декабря 2009
Implements IDisposable

Public Overloads Sub Dispose() Implements IDisposable.Dispose

    Dispose(True)
    GC.SuppressFinalize(Me)

End Sub

Protected Overloads Sub Dispose(ByVal disposing As Boolean)

    If disposing Then
        ' Free other state (managed objects).
    End If
    ' Free your own state (unmanaged objects).
    ' Set large fields to null.
End Sub

Protected Overrides Sub Finalize()

    Dispose(False)
    MyBase.Finalize()

End Sub
1 голос
/ 22 сентября 2008

Как уже говорили другие, вам не нужно реализовывать финализатор, если вы непосредственно не владеете неуправляемыми ресурсами. Кроме того, при условии, что вы работаете в .NET 2.0 или более поздней версии, вряд ли вам когда-либо понадобится реализовать финализатор, поскольку обычно SafeHandle может использоваться для упаковки ваших неуправляемых ресурсов.

Я написал довольно длинное сообщение в блоге , посвященное истории и реализации IDisposable и финализаторов некоторое время назад, которое может стоить прочитать, если вы не совсем понимаете об этом.

...