2010-02-15 3 views
2
Class ComponentsContainer ' a component contains other components' 
    Inherits System.ComponentModel.Component 

    Private foo as New Component 
    Private bar as New Component 

Protected Override Sub Finalize() 
    foo.Dispose() ' HERE ? ' 
    bar.Dispose() 
    MyBase.Finalize() 
End Sub 

Protected Overrides Sub Dispose(disposing As Boolean) 
    If disposing Then 
     foo.Dispose() ' OR HERE ? ' 
     bar.Dispose() 
    End If 
    MyBase.Dispose(disposing) 
End Sub 
End Class 

ответ

3

Вы не должны (не обязательно) Dispose управляемые ресурсы из Finalizer:

Protected Override Sub Finalize() 
    ' foo.Dispose() ' 
    ' bar.Dispose() ' 
    MyBase.Finalize() 
End Sub 

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

Примечание: в вашем классе отсутствует перегрузка Public Sub Dispose().

Edit:

С foo и bar управляются ресурсы (простирающиеся компонент) требуется только метод Protected Overrides Sub Dispose(disposing As Boolean). Версия в вопросе верна. И просто снимите Finalize().

+0

Подозреваемый перегрузка 'Public Sub Dispose' происходит из базового класса – MarkJ

+0

Я обновил код, объясняющий, откуда я наследую. У меня есть компонент, который содержит 2 других компонента. – serhio

+0

@MarkJ, вы правы, и serhio сделал это уверенным. –

3

Финализатор должен вызывать этот класс 'Dispose передать false для параметра размещения, а не прямо распоряжаться объектами, которыми владеет этот класс. См. MSDN.

Редактировать: Чтобы ответить на вопрос, удаление принадлежащих им объектов должно быть выполнено в Dispose, а не в Finalize.

Edit 2: Обратите внимание, это означает, что если объект будет завершен без утилизировать, то Dispose только дозвонился (по Finalize) «ложным» параметр, и дочерние объекты не будут захоронены этим класс. Это правильно, потому что они являются управляемыми объектами и будут завершены, когда среда будет выглядеть так, как если бы она не была явно удалена.

+0

Исправить. И в этом примере Dispose (False) ничего не делает (кроме, может быть, в базовом классе). Лучшим вариантом было бы удаление как Finalize, так и Dispose (bool). –

+0

Итак, наконец, где я должен распоряжаться foo и bar? – serhio

+0

В методе Dispose. – BlueMonkMN

1

Dispose - это когда вы явно хотите освободить некоторые ресурсы, прежде чем сборщик мусора освободит объект.

Finalize автоматически вызывается, когда сборщик мусора обходит вокруг, чтобы освободить объект.

Если у вас есть много объектов, которые держатся за ресурсы, тогда, поскольку вы не должны контролировать сбор мусора, вы должны использовать Dispose.

Из документации рамочной:

Обратите внимание, что даже если вы предоставите явное управление посредством Dispose, вы должны обеспечить неявную очистку с использованием метода Finalize. Финализация обеспечивает резервную копию, чтобы предотвратить утечку ресурсов из-за постоянного утечки, если программист не может вызвать Dispose.

Implementing Finalize and Dispose to Clean Up Unmanaged Resources

+0

Итак, явная очистка в моем случае должна быть 'foo.Dispose' и' bar.Dispose', теперь что может означать «неявная очистка» в Finalize в моем случае, я не вижу ... – serhio

1

Что вы наследующий? Я подозреваю, что это может быть System.ComponentModel.Container, прямо или косвенно.

В этом случае вам ничего не нужно делать. System.ComponentModel.Container automatically содержит любые компоненты, которые он содержит, в своем методе Dispose. Оставьте это в покое - это должен быть самый простой способ реализовать шаблон dispose/finalize.

+0

Наследование от 'System.ComponentModel . Компонент'. Обновлен код. – serhio

+0

Почему бы не наследовать от Контейнера? Вот для чего это. – MarkJ

+0

В реальном проекте я использую VisualBasic.PowerPacks.Shape (это компонент). Итак, у меня есть настраиваемая (многострочная) форма, содержащая некоторые внутренние фигуры (линии). – serhio

Смежные вопросы