2017-03-01 56 views
0

我必须在另一个线程中显示进度窗口。 这是我做了什么:在新线程中加载窗口

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! Ty!

+4

不要在除主/ UI线程以外的任何线程上做UI东西。这是一条基本规则。相反,通过在工作线程上正确调用UI线程上的更新代码来更新进度指示器。 –

+0

切换你的计划。将工作推送到另一个线程,并在主线程上启动/显示/控制加载窗口。 – Skintkingle

+0

不幸的是我必须在主线程中执行这个操作。我找到了这篇文章(https://strukachev.wordpress.com/2011/01/09/wpf-progress-window-in-separate-thread/),这是一个好方法吗? –

回答

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(); 

然后,您可以移动线的启动,以及线程监控/关闭该窗口,进入加载类,它可以照看呀。

有900,000种方法可以做到这一点。你也可以使用BackgroundWorkers而不是产生一个新的Thread,或者你可以在.Net 4.5+中使用async/await。像这样的线程已经在过去彻底完成,并且应该有大量的谷歌资源来帮助你在你决定采取的任何路径。从这个重要的结果是你的窗口应该真的在UI线程上,你的加载应该在另一个线程上完成,而不是相反。

+0

异步/等待不需要额外的线程 – VMAtm

0

你可以参考下面的博客文章如何在一个单独的线程启动一个WPF窗口的正确方法的例子:http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/

但你不能混用那些在不同的线程创建的控件。一个控件只能在它最初创建的线程上访问,所以在一个线程上创建一个控件,然后尝试在另一个线程上使用它是没有意义的,因为这是因为线程亲和性而无法工作的。

期间正在进行的长时间运行的操作是显示一个独立的顶级只读窗口是好的,但你应该尽快关闭该窗口的操作已完成。无论如何,您将无法将控件从此窗口移到另一个线程上创建的另一个窗口。