过去一天左右,我一直试图解决这个问题。
我有一个包含Form1的程序,以及一个在新线程中生成Form2的按钮。
我在Form1上还有另一个按钮,它应关闭Form2,但由于Form2在另一个线程中,我无法直接触摸该对象。
我可以做t.Abort()
,但会引发异常。
我怎样才能优雅地触摸另一个线程?做点东西吗?
例如,如何从Form1中关闭表单?
我搜索了谷歌“如何从另一个线程中关闭一个表单”,并找到了几个暗示Invoke和Delegate的链接,但在尝试了一些事情之后,我显然无法弄清楚如何正确使用它。 / p>
任何人都可以帮助我理解它如何应用于我的代码,以便我能理解它们如何被使用?在哪种情况下?
为方便起见,我已将项目上传到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]
有其他表单代码。
答案 0 :(得分:2)
一般来说,为两种形式设置两个线程并不是一个好主意。将所有表单放在主要的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;
}
}