2

在过去的一天左右,我一直试图弄清楚这一点。

我有一个具有 Form1 的程序,以及一个在新线程中生成 Form2 的按钮。

我在 Form1 上还有另一个按钮应该关闭 Form2,但由于 Form2 在另一个线程中,我无法直接触摸该对象。

我可以这样做t.Abort(),但这会引发异常。

我怎样才能优雅地触摸另一根线?为它做事?

例如,如何从 Form1 中关闭表单?

我在 google 上搜索了“如何从另一个线程中关闭表单”,并找到了几个暗示 Invoke 和 Delegate 的链接,但是在尝试了一些事情之后,我显然无法弄清楚如何正确使用它。

谁能帮助我了解它如何应用于我拥有的代码,以便我了解如何使用它们?在什么情况下,等等?

为方便起见,我已将项目上传到 github:https ://github.com/powercat/WindowsFormsApplication7/archive/master.zip

--

代码:

[Form1.cs]

    public void FormThread()
    {
        Application.Run(new Form2());
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(FormThread));
        t.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {

        //Need to close Form2 from here.

    }

[Form2.cs]

有其他表单代码。

4

1 回答 1

3

一般来说,为两种形式设置两个线程并不是一个好主意。将所有表单放在主 UI 线程上,然后将逻辑和工作转移到后台线程上几乎总是一个更好的主意。

话虽如此,如果表单在单独的线程中运行,您应该能够使用BeginInvoke它来关闭它:

 otherForm.BeginInvoke(new Action(() => otherForm.Close()));

编辑:

在您的情况下,您需要保存实例:

Form2 otherForm;
public void FormThread()
{       
    otherForm = new Form2();
    Application.Run(otherForm);
}

private void button1_Click(object sender, EventArgs e)
{
    Thread t = new Thread(new ThreadStart(FormThread));
    t.SetApartmentState(ApartmentState.STA); // THIS IS REQUIRED!
    t.Start();
}

private void button2_Click(object sender, EventArgs e)
{
    //Need to close Form2 from here.
    if (otherForm != null)
    {
       otherForm.BeginInvoke(new Action( () => otherForm.Close() ));
       otherForm = null;
    }
}
于 2013-10-25T17:33:41.273 回答