C#从另一个线程调用form.show()

如果我从另一个线程调用WinForms对象上的form.show() ,表单将抛出exception。 我可以通过何种方式向主应用程序线程添加新的可见表单? 否则,如何在不停止当前正在执行的线程的情况下打开表单?

这是我的示例代码。 我试图启动一个线程,然后在该线程中执行一些工作。 随着工作的进展,我将展示表格。

 public void Main() { new Thread(new ThreadStart(showForm)).Start(); // Rest of main thread goes here... } public void showForm() { // Do some work here. myForm form = new myForm(); form.Text = "my text"; form.Show(); // Do some more work here } 

尝试使用调用调用:

 public static Form globalForm; void Main() { globalForm = new Form(); globalForm.Show(); globalForm.Hide(); // Spawn threads here } void ThreadProc() { myForm form = new myForm(); globalForm.Invoke((MethodInvoker)delegate() { form.Text = "my text"; form.Show(); }); } 

“调用”调用告诉表单“请在您的线程中执行此代码而不是我的代码”。 然后,您可以从委托中更改WinForms UI。

有关Invoke的更多文档,请访问: http : //msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

编辑:您将需要使用已存在的WinForms对象来调用invoke。 我在这里展示了如何创建一个全局对象; 否则,如果你有任何其他windows对象,那些也将工作。

调用form.Show()后,应调用Application.Run() form.Show() 。 例如:

 public void showForm() { // Do some work here. myForm form = new myForm(); form.Text = "my text"; form.Show(); Application.Run(); // Do some more work here } 

至于原因背后的细节, 这个msdnpost可能有所帮助。

根据我的经验最好的方法:

 var ac = (ReportPre)Application.OpenForms["ReportPre"]; Thread shower = new Thread(new ThreadStart(() => { if (ac == null) { this.Invoke((MethodInvoker)delegate () { ac = new ReportPre(); ac.Show(); }); } else { this.Invoke((MethodInvoker)delegate { pictureBox1.Visible = true; }); if (ac.InvokeRequired) { ac.Invoke(new MethodInvoker(delegate { ac.Hide(); ac.Show(); })); } } })); shower.Start();