2013-10-22 18 views
0

我需要spawn a Form可以像往常一样使用,但主线程必须继续进行之后的任何操作。当我尝试2个技术下面我不能使用形式:如何生成表单并且不阻塞主线程?

static class Program 
{ 
    private static void spawnForm1() 
    { 
     new Form1().Show(); 
    } 

    private static void spawnForm2() 
    { 
     // solved: use ShowDialog() instead of Show() here 
     ThreadPool.QueueUserWorkItem(o => { new Form1().Show(); }); 
    } 

    [STAThread] 
    static void Main() 
    { 
     spawnForm1(); 
     MessageBox.Show("main thread continues"); 
     // now anything can happen: background processing or start of main form 
     // sleeping is just an example for how the form is unresponsive 
     Thread.Sleep(30 * 1000); 
    } 
} 

所以,我怎么能生成一个简单的表格,继续在主线程?它应该像消息框一样响应。

(我不能使用Application.Run(...);,我不能用ShowDialog()是否会阻塞主线程,也:我很抱歉,我没有太多的声誉,但是这不是一个noob问题,我真的需要它会像我试图解释的那样产生)

+0

这听起来像是一个严重的设计问题。 * my * WinForm应用程序中的主线程始终负责UI,而其他线程(线程池和/或后台工作者)负责其他非可视化作业。你的问题在我看来,你想要做的只是另一种方式。 –

+0

@UweKeim主窗口像应用程序一样总是运行。但是我需要产生一个窗口,就像我在现有的主窗口中描述的一样,也没有它。 – Bitterblue

+1

从主线程启动一个窗口,并在该窗口中进行后台处理。 –

回答

1

你的代码不工作,因为没有消息循环。您只需启动UI元素的消息循环以正常工作。这意味着在某些时候您必须致电Application.RunForm.ShowDialog

我看不出为什么你不能使用UI的入口点线程,然后创建一个工作线程去做任何你想在UI运行时发生的事情。

[STAThread] 
public static void Main() 
{ 
    Task.Run(() => DoOtherStuff()); 
    Application.Run(new YourForm()); 
} 

在评论你的写到:

主窗口由应用程序像往常一样跑了。但我需要产生一个窗口,就像我在现有主窗口 中描述的那样,也没有它。

我假设你的意思是你要运行的入口点线程和一个单独的线程上都Form实例。我的建议是避免这样做。它不能很好地工作。有很多奇怪的事情可能发生。重新思考你的设计,以便有一个且只有一个UI线程。将耗时的操作移至工作线程。

+0

我只接受第一段的答案。它帮助我找到了错误。我忘了每个窗口都需要一个消息循环。 – Bitterblue

3

不要创建一个新线程来显示UI。你在UI线程中,它应该是显示窗体的那个。产生一个新的线程来做你想做的非UI工作:

[STAThread] 
static void Main() 
{ 
    Task.Run(()=> 
     { 
      //do non-UI work here 
      Thread.Sleep(30 * 1000); 
     }); 
    Application.Run(new Form1()); 
}