C# 如何从另一个线程中的窗体关闭新线程中的窗体?
在过去的一天左右,我一直在想这个问题 我有一个包含Form1的程序,还有一个在新线程中生成Form2的按钮 我在Form1上还有一个按钮可以关闭Form2,但是因为Form2在另一个线程中,我不能直接触摸那个对象 我可以执行C# 如何从另一个线程中的窗体关闭新线程中的窗体?,c#,winforms,C#,Winforms,在过去的一天左右,我一直在想这个问题 我有一个包含Form1的程序,还有一个在新线程中生成Form2的按钮 我在Form1上还有一个按钮可以关闭Form2,但是因为Form2在另一个线程中,我不能直接触摸那个对象 我可以执行t.Abort(),但这会引发异常 我怎样才能优雅地触摸另一根线?对它做些什么 例如,如何从Form1中关闭表单 我在谷歌上搜索了“如何从另一个线程中关闭表单”,并找到了几个提示Invoke和Delegate的链接,但在尝试了一些东西之后,我显然不知道如何正确使用它 有谁能帮
t.Abort()
,但这会引发异常
我怎样才能优雅地触摸另一根线?对它做些什么
例如,如何从Form1中关闭表单
我在谷歌上搜索了“如何从另一个线程中关闭表单”,并找到了几个提示Invoke和Delegate的链接,但在尝试了一些东西之后,我显然不知道如何正确使用它
有谁能帮助我理解它将如何应用到我的代码中,以便我理解如何使用它们?在哪种情况下,等等
为了方便您,我已将项目上载到github:
--
代码:
[表格1.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.
}
[表格2.cs]
有另一个表单代码。一般来说,两个表单有两个线程不是一个好主意。将所有表单放在主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;
}
}
不要使用多LPE UI线程。别这样。它会让你的生活陷入地狱,而winforms框架并不是为了支持它而构建的。为你的程序使用一个UI线程。你应该只粘贴你在文章中尝试的代码。我不打算在我的计算机上打开该文件。我无法从工作地点访问GitHub。只需将代码粘贴到创建和启动线程的位置。谢谢,我添加了一些代码。但是如果我启动另一个UI窗口,前一个窗口是“冻结”的,这就是我使用另一个线程的原因。Reed Copsey建议使用Backgroundworker,这是正确的方法吗?@PowerCat如果你阻止你的UI线程进行非UI工作,那么这就是一个问题。您可以通过在非UI线程中执行非UI工作来修复它,而不是创建两个UI线程并阻止一个表单而不是另一个表单。谢谢。我一直在看“其他形式”,但这是我不明白的部分之一。什么是“其他形式”?它如何与代码相匹配?我将查看后台线程。当我键入Form2时,“BeginInvoke”方法不会出现在intellisense上。这个BeginInvoke是我在其他答案上看到的,但是我从来没有在我的代码中实现过。对不起,我不明白。请您指出我要在哪一行,哪一个文件中加上这一行好吗?既然我无法在该事件中添加该命令,我将如何使button2\u Click执行该命令?@PowerCat您需要将
new Form2()
实例保存在某个地方,并有权访问它。@PowerCat为您添加了代码-请注意STA线程调用(您也需要它)