views:

509

answers:

2

I get a System.InvalidOperationException error when i close my app before the search is done. When i close on Form1_FormClosing i tell all my threads to abort. In one thread it has finalize which calls a delegate function which tells one of the controls in the form to change its text. When that happens I get the exception above along with "Additional information: Invoke or BeginInvoke cannot be called on a control until the window handle has been created."

What can i do to correct this? i could add a isClosing flag and check it before updating the text but that feels like a hack and masking the problem. How do i correctly solve this?

+1  A: 

This is happening because the managed control is being disposed and no longer has its handle, but you haven't closed the window yet so you still see it.

You could create a function that would wrap the Invoke call and would check for IsHandleCreated before calling Invoke. If IsHandleCreated is false, you cannot call Invoke and you can just ignore the call.

public static class ControlExtensions
{
  public static TResult InvokeEx<TControl, TResult>(this TControl control,
                                          Func<TControl, TResult> func)
    where TControl : Control
  {
    if (!control.IsHandleCreated)
      return default(T);

    if (control.InvokeRequired)
      return (TResult)control.Invoke(func, control);
    else
      return func(control);
  }

  public static void InvokeEx<TControl>(this TControl control,
                                        Action<TControl> action)
    where TControl : Control
  {
    control.InvokeEx(c => { action(c); return c; });
  }
}

So now just wrap any Invokes from your threads with InvokeEx and it will handle when a control has been disposed and no longer has a handle.

this.InvokeEx(c => c.label1.Text = "Hello world");
Samuel
+1  A: 

I agree with Samuel, but would also check IsDisposed:

void Handler()
{
  if (ctrl.IsDisposed || !ctrl.IsHandleCreated) return;
  if (ctrl.InvokeRequired) 
    Invoke(...);
  else {
    ...
  }
}
Bob Nadler