In order to verify the above-mentioned disposable behavior, I've created a Windows Application project implementing two components (you can download the solution by clicking the download link above). The SimpleComponent class was created WITHOUT the New(IContainer) constructor. The ContainedComponent class was created WITH the New(IContainer) constructor:
Public Class SimpleComponent
Inherits System.ComponentModel.Component
Public Sub New()
MyBase.New()
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
Debug.WriteLine(String.Format("{0}({1})", Me.GetType().FullName, disposing))
MyBase.Dispose(disposing)
End Sub
End Class
Public Class ContainedComponent
Inherits System.ComponentModel.Component
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal Container As System.ComponentModel.IContainer)
Me.New()
Container.Add(Me)
End Sub
Protected Overloads Overrides Sub Dispose( _
ByVal disposing As Boolean)
Debug.WriteLine(String.Format("{0}({1})", Me.GetType().FullName, disposing))
MyBase.Dispose(disposing)
End Sub
End Class
After recompiling the solution, I was able to add the two components to the Visual Studio .NET toolbox and I've dropped both of the components onto a DialogForm form class. Here is the instantiation code that the Windows Forms designer generated for the two components:
#Region " Windows Form Designer generated code "
...
Me.components = New System.ComponentModel.Container
Me.SimpleComponent1 = New DisposableComponents.SimpleComponent
Me.ContainedComponent2 = New DisposableComponents.ContainedComponent(Me.components)
...
#End Region
Because the ContainedComponent class exposes the New(IContainer) constructor, the designer generated code to call this constructor instead of the default one. In the constructor, the ContainedComponent instance adds itself to the Form.components container, so it is automatically disposed when the Form's Dispose(Boolean) method is called.
In contrast, the SimpleComponent instance does not really know when the owning Form is disposed, so it remains alive until it becomes garbage-collected eventually.
In the application's main form, the following code is used to display the DialogForm containing the two components:
Private Sub ShowDialogButton_Click(...)
Dim Dialog As DialogForm
Try
Dialog = New DialogForm
Dialog.ShowDialog(Me)
Catch ex As Exception
Trace.WriteLine(ex.ToString())
MsgBox(ex.Message, MsgBoxStyle.Exclamation)
Finally
If Not Dialog Is Nothing Then
Dialog.Dispose()
End If
End Try
End Sub
When you run the application and click the ShowDialogButton button, the DialogForm instance is displayed. If you dismiss the dialog, the DialogForm.Dispose method is called and you'll see in the Output window that the ContainedComponent.Dispose method has been called as well.
In contrast, the SimpleComponent instance is NOT disposed until after the application is ended or until garbage collection takes place. (It might happen if you create and destroy several instances of the DialogForm so enough memory is allocated that a threshold for the garbage collection is reached. Just press and hold the ENTER key and you'll reach the threshold quickly).
Comments