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

scz*_*vos 19 c# multithreading .net-3.5 winforms

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

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

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
}
Run Code Online (Sandbox Code Playgroud)

Ted*_*nce 33

尝试使用调用调用:

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();
    });
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 使用lambdas而不是委托. (2认同)

小智 13

你打电话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
}
Run Code Online (Sandbox Code Playgroud)

至于原因背后的细节,这个msdn帖子可能有所帮助.

  • 这将在另一个线程中启动一个新的消息循环 - 当已经在主线程上运行时,启动新的消息循环可能过多了... (5认同)