2017-03-01 84 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/

但你不能混用那些在不同的線程創建的控件。一個控件只能在它最初創建的線程上訪問,所以在一個線程上創建一個控件,然後嘗試在另一個線程上使用它是沒有意義的,因爲這是因爲線程親和性而無法工作的。

期間正在進行的長時間運行的操作是顯示一個獨立的頂級只讀窗口是好的,但你應該儘快關閉該窗口的操作已完成。無論如何,您將無法將控件從此窗口移到另一個線程上創建的另一個窗口。