如何从非gui线程C#中创建表单

我有一个主GUI,我从一个单独的线程中开始一个长时间运行的方法。 现在,在这个单独的线程中,我需要创建并显示一个新表单。 但是,当我显示这个新表单时,所有控件都被卡住,窗口显示“没有响应”。

哪种解决方法最好?

问候

托马斯

将创建新GUI的代码放入主GUI类,然后调用主GUI的Invoke方法,或者引发主GUI可以订阅的事件,以了解何时触发新GUI。 如果选择后者,请确保使用InvokeRequired确定是否可以直接调用创建新GUI的方法,或者是否需要使用Invoke返回GUI线程来创建新GUI。

您需要了解Control.BeginInvoke / Invoke以及所有这些。 请记住,所有UI操作都需要在主线程(UI线程)上进行,因为这是拥有消息泵的线程。 您需要回调该线程才能执行UI操作。

这是BeginInvoke / Invoke的介绍: http : //weblogs.asp.net/justin_rogers/pages/126345.aspx

为了进一步提供帮助,这里有一个完整的工作代码示例,应该突出基础知识。

public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var worker = new Worker(this); worker.Start(); } public void updateLabel(int value) { if(label1.InvokeRequired) { // check if on UI thread //If true use begin invoke to call update on UI thread //this calls the anonymous delegate in the UI thread //that then calls the updateLabel function again to set the label's text label1.BeginInvoke(new MethodInvoker(() => this.updateLabel(value))); return; } label1.Text = value.ToString(); } public void showNewForm() { if(this.InvokeRequired) { // check if on UI thread this.BeginInvoke(new MethodInvoker(this.showNewForm)); // we need to create the new form on the UI thread return; } var anotherForm = new Form1(); anotherForm.Show(); } } class Worker { private volatile bool stop = false; private Form1 form; public Worker(Form1 form) { this.form = form; } public bool Stop { get { return stop; } set { stop = value; } } public void Start() { var thread = new Thread(this.work); thread.IsBackground = true; thread.Start(); } private void work() { int i = 0; while(!stop) { i++; Thread.Sleep(100); form.updateLabel(i); if(i == 50) { form.showNewForm(); // call into form // can also do the invokerequired check here and create new form w/ anonymous functions // however, I'd recommend keeping all the UI code in the same place. } } } } 

使用Form.Show而不是Form.ShowDialog。 您还可以使用BackgroundWorker执行并发任务。