2008-08-21

Error creating window handle.

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: