I have been chasing a bug in a VB.NET Windows Forms application today. The error log was filled with Win32Exception Error creating window handle. Digging in the usage log I loacted the following code.
1: Public Sub DataBindRadioButton(ByVal radioButton As Windows.Forms.RadioButton, ByVal radioButtonTrueValue As Object, ByVal radioButtonFalseValue As Object, ByRef dataSource As Object, ByVal dataMember As String)
2: Dim propertyHolder As New propertyHolder(radioButton, radioButtonTrueValue, radioButtonFalseValue, dataSource, dataMember)
3: propertyHolder.Name = radioButton.Name & "propertyHolder"
4:
5: For Each control As control In radioButton.FindForm.Controls
6: If control.Name = propertyHolder.Name Then
7: radioButton.FindForm.Controls.Remove(control)
8: Exit For
9: End If
10: Next
11:
12: radioButton.FindForm.Controls.Add(propertyHolder)
13: End Sub
propertyHolder is a Control.
So whats the memory leak here?
radioButton.FindForm.Controls.Remove(control), since we remove the control from the container(Form). We now inherit the responsibility to clean up.
So a non leaking version would be.
1: Public Sub DataBindRadioButton(ByVal radioButton As Windows.Forms.RadioButton, ByVal radioButtonTrueValue As Object, ByVal radioButtonFalseValue As Object, ByRef dataSource As Object, ByVal dataMember As String)
2: Dim propertyHolder As New propertyHolder(radioButton, radioButtonTrueValue, radioButtonFalseValue, dataSource, dataMember)
3: propertyHolder.Name = radioButton.Name & "propertyHolder"
4:
5: For Each control As control In radioButton.FindForm.Controls
6: If control.Name = propertyHolder.Name Then
7: radioButton.FindForm.Controls.Remove(control)
8: control.Dispose()
9: Exit For
10: End If
11: Next
12:
13: radioButton.FindForm.Controls.Add(propertyHolder)
14: End Sub
So remember to dispose a control when you dynamically remove it from its container.
The application also had a while loop that in some conditions never exited, and called the above method.
No comments:
Post a Comment