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