在新线程中加载窗口

时间:2017-03-01 16:07:39

标签: c# wpf multithreading

我必须在不同的线程中显示进度窗口。 这就是我所做的:

Thread loadT = new Thread(new ThreadStart(() =>
{
    Loading ldd = new Loading();

    ldd.SetContentMessage("Loading...");
    ldd.Closed += (s, ec) =>
    Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);

    ldd.ShowDialog();

}));
loadT.SetApartmentState(ApartmentState.STA); 

loadT.Start();

//do something

loadT.Abort();

但我不认为这是正确的方法。我想将此窗口用于不同的进程,我还想将窗口设置在其他窗口的顶部。哪种方法最好? TY!

2 个答案:

答案 0 :(得分:1)

当您等待数据和要加载的内容时,您应该以相反的方式执行此操作。

Loading ldd = new Loading();
ldd.SetContentMessage("Loading...");
ldd.ShowDialog();
Thread loadT = new Thread(new ThreadStart() => 
{
    //Do stuff here
});
loadT.Start();

然后你可以设置一些事件,比如发布加载窗口的更新,或者保持原样。您还可以监视“加载”窗口中的线程状态,并在线程完成时关闭自身,或者从线程关闭窗口。

作为示例,您可以修改“加载”以将“线程”作为其参数。

Thread loadT = new Thread(new ThreadStart() => 
{
    //Do stuff here
});
Loading ldd = new Loading(loadT);
ldd.ShowDialog();

然后,您可以移动线程的开始,监视线程/关闭窗口到Loading类,它可以自己管理。

有90万种方法可以做到这一点。您也可以使用BackgroundWorkers而不是生成新的Thread,或者您可以在.Net 4.5+中使用async / await。像这样的线程在过去已经详尽地完成,谷歌应该有很多资源来帮助你做出你决定采取的任何方式。重要的是,你的窗口应该在UI线程上,你的加载应该在另一个线程上完成,而不是相反。

答案 1 :(得分:0)

您可以参考以下博客文章,了解如何以正确的方式在单独的线程中启动WPF窗口的示例:http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/

但是您将无法混合在不同线程上创建的控件。控件只能在最初创建它的线程上访问,所以在一个线程上创建一个控件然后尝试在另一个线程上使用它是没有意义的,因为由于线程关联性,这根本不起作用。

在长时间运行的操作过程中显示独立的顶级只读窗口是可以的,但是您应该在操作完成后立即关闭此窗口。您无法将控件从此窗口移动到另一个在另一个线程上创建的控件。