如果我从另一个线程调用WinForms对象上的form.show()
,表单将抛出异常。有什么方法可以将新的、可见的表单添加到主应用程序线程中吗?否则,如何在不停止当前正在执行的线程的情况下打开窗体?
以下是我的示例代码。我正在尝试启动一个线程,然后在该线程中执行一些工作。随着工作的进展,我将展示表单。
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
}
发布于 2012-08-17 05:16:55
尝试使用invoke调用:
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();
});
}
"invoke“调用告诉表单”请在您的线程中而不是我的线程中执行此代码。“然后,可以从代理中对WinForms UI进行更改。
有关Invoke的更多文档在这里:http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
编辑:您需要使用已经存在的WinForms对象才能调用invoke。我已经在这里展示了如何创建一个全局对象;否则,如果您有任何其他窗口对象,这些对象也可以工作。
发布于 2013-04-12 08:29:40
您应该在调用form.Show()
之后调用Application.Run()
。例如:
public void showForm()
{
// Do some work here.
myForm form = new myForm();
form.Text = "my text";
form.Show();
Application.Run();
// Do some more work here
}
至于原因背后的细节,this msdn post可能会有所帮助。
发布于 2018-07-31 03:19:58
根据我的经验,最好的方法是:
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();
https://stackoverflow.com/questions/11995466
复制相似问题