C# 从另一个线程调用 form.show()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11995466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# calling form.show() from another thread
提问by sczdavos
if I call form.show()on a WinForms object from another thread, the form will throw an exception. Is where any way I can add a new, visible form to the main app thread? Otherwise, how can I open the form without stopping my currently executing thread?
如果我form.show()从另一个线程调用WinForms 对象,该表单将引发异常。有什么方法可以向主应用程序线程添加一个新的可见表单?否则,如何在不停止当前正在执行的线程的情况下打开表单?
Here is my sample code. I am attempting to start a thread and then execute some work within that thread. As the work progresses, I will show the form.
这是我的示例代码。我正在尝试启动一个线程,然后在该线程中执行一些工作。随着工作的进行,我将展示表格。
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
}
采纳答案by Ted Spence
Try using an invoke call:
尝试使用调用调用:
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();
});
}
The "invoke" call tells the form "Please execute this code in your thread rather than mine." You can then make changes to the WinForms UI from within the delegate.
“invoke”调用告诉表单“请在您的线程而不是我的线程中执行此代码。” 然后,您可以从委托中更改 WinForms UI。
More documentation about Invoke is here: http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
关于 Invoke 的更多文档在这里:http: //msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
EDIT: You will need to use a WinForms object that already exists in order to call invoke. I've shown here how you can create a global object; otherwise, if you have any other windows objects, those will work as well.
编辑:您需要使用已经存在的 WinForms 对象才能调用 invoke。我在这里展示了如何创建全局对象;否则,如果您有任何其他 windows 对象,它们也将起作用。
回答by Hiroshi Maekawa
You should call Application.Run()after you call form.Show(). For example:
你应该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
}
As for the details behind why, this msdn postmay help.
至于原因背后的细节,这篇 msdn post可能会有所帮助。
回答by Mohamad Taheri
The best way by my experience:
根据我的经验最好的方法:
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();

