使用Invoke方法从外部线程关闭表单

Alf*_*ort 4 c# multithreading invoke winforms

我必须从线程关闭Form,并且正在使用Form的Invoke方法调用Close()方法。

问题是,关闭时将处理该窗体,并且我收到一条InvalidOperationExecption消息:“在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke”。

仅当在Close方法中使用“ Step Into”进行调试时,我才遇到此异常,但是我不想冒险在正常运行时可能出现错误。

这是重现它的示例代码:

 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.
         } 
     ));
 }
Run Code Online (Sandbox Code Playgroud)

表单以自动生成的表单代码(我不希望对其进行修改)处理:

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
Run Code Online (Sandbox Code Playgroud)

如果有人可以为我提供这种方法或其他方法来关闭另一个线程中的表单,我将不胜感激。

56k*_*6ka 5

使用此方法:

// 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

Functions.InvokeIfRequired(anyControl, (MethodInvoker)delegate()
{
    // UI stuffs
});
Run Code Online (Sandbox Code Playgroud)