Close a form from an external thread using the Invoke method

c#, invoke, multithreading, winforms

Solution

Use this method :

// Inspired from: http://stackoverflow.com/a/12179408/1529139
public static void InvokeIfRequired(Control control, MethodInvoker action)
{
    if (control.IsDisposed)
    {
        return;
    }

    if (control.InvokeRequired)
    {
        try
        {
            control.Invoke(action);
        }
        catch (ObjectDisposedException) { }
        catch (InvalidOperationException e)
        {
            // Intercept only invokation errors (a bit tricky)
            if (!e.Message.Contains("Invoke"))
            {
                throw e;
            }
        }
    }
    else
    {
        action();
    }
}

Usage example:

Functions.InvokeIfRequired(anyControl, (MethodInvoker)delegate()
{
    // UI stuffs
});

Problem

I have to close a Form from a thread and I am using the Invoke method of the Form for calling the Close() method. The problem is that when closing, the form is disposed and I get an InvalidOperationExecption wit the message "Invoke or BeginInvoke cannot be called on a control until the window handle has been created.". I have got this exception only when debugging with a "Step Into" in the Close method but I don't want to risk with a possible error on normal running. This is an example code to reproduce it: ``` private void Form1_Load(object sender, EventArgs e) { Thread thread = new Thread(CloseForm); thread.Start(); } private void CloseForm() { this.Invoke(new EventHandler( delegate { Close(); // Entering with a "Step Into" here it crashes. } )); } ``` The form is disposed in the automatic generated code for the form (which I would like not to modify): ``` protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } ``` I would appreciate it if someone could give me a solution for this or another way to close a form from another thread.

Original source

Related problems