【问题标题】:How to close a form on a new thread from a form which is in another thread?如何从另一个线程中的表单关闭新线程上的表单?
【发布时间】:2013-10-25 17:30:55
【问题描述】:

过去一天左右我一直在努力解决这个问题。

我有一个包含 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]

有其他表单代码。

【问题讨论】:

  • 不要使用多重 UI 线程。只是不要。它会让你的生活变得地狱,而 winforms 框架并不是真正为支持它而构建的。为您的程序使用单个 UI 线程。
  • 您应该在帖子中粘贴您正在尝试的代码。我不会在我的电脑上打开那个文件。
  • 我无法从我的工作地点访问 GitHub。只需将代码粘贴到您创建并启动线程的位置即可。
  • 谢谢,我已经添加了一些代码。但是如果我启动另一个 UI 窗口,前一个窗口会“冻结”,这就是我使用另一个线程的原因。 Reed Copsey 建议使用 BackGroundWorkers,这是正确的做法吗?
  • @PowerCat 如果您阻止 UI 线程执行非 UI 工作,那么这是一个问题。您可以通过在非 UI 线程中执行非 UI 工作来修复它,而不是通过创建两个 UI 线程并阻塞一个表单而不是另一个表单。

标签: c# winforms


【解决方案1】:

一般来说,为两个表单设置两个线程并不是一个好主意。将所有表单放在主 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;
    }
}

【讨论】:

  • 谢谢。我一直看到“otherForm”,但这是我不明白的部分之一。什么是“其他形式”?它如何与代码匹配?我会调查后台线程。
  • 当我输入 Form2 时,“BeginInvoke”方法没有出现在智能感知上。这个 BeginInvoke 是我在其他答案中看到的,但从未能够在我的代码中实现它。
  • 对不起,我不明白。您能指出我将在哪个文件中添加该行吗?以及我如何让 button2_Click 执行该命令,因为我无法在该事件中添加它?
  • @PowerCat 您需要将new Form2() 实例保存在某处 - 并有权访问它。
  • @PowerCat 为您添加了代码 - 也请注意 STA 线程调用(您将需要它)
猜你喜欢
  • 2013-08-21
  • 2015-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 2011-01-16
相关资源
最近更新 更多