2011-04-06 40 views
4

我想要做的事:如何在單獨的線程中打開一個窗口?

Window newWindow = new Window(); 
newWindow.Show(); 

while (true) 
{ 
    Console.Write("spin"); 
} 

也就是說,我做在主窗口中的密集計算,但是這個新窗口(這裏我試圖以顯示與動畫繁忙的指標)不響應(它的冷凍)...

於是,我就這樣做:

Thread thread = new Thread(() => 
{ 
    Window newWindow = new Window(); 
    newWindow.Show(); 
}); 

thread.SetApartmentState(ApartmentState.STA); 
thread.Start(); 

while (true) 
{ 
    Console.Write("spin"); 
} 

但新的窗口仍然凍結等 任何人都知道什麼是錯在這裏?

+1

爲什麼不只是在另一個線程上執行你的工作? – 2011-04-06 17:02:21

回答

8

您不應該嘗試在自己的線程中打開一個新窗口。

相反,將您正在執行的計算工作推入後臺線程,並使UI線程空閒。最簡單的選擇是使用BackgroundWorker。它會自動處理進度和完成回傳到UI線程。

但是,您可以自己使用線程或Task/Task<T>來做到這一點。請記住使用從UI上下文創建的Dispatcher或TaskScheduler來處理任何會更新UI的任務,例如進度通知。

+0

「計算工作」實際上是一個正在顯示的新窗口(除了newWindow)。我正在加載一個需要一段時間才能加載的新窗口。 – foreyez 2011-04-06 17:00:22

+1

@foreyez:通常可以通過「新窗口」將非UI計算移動到後臺線程中,並完全避免此問題。 – 2011-04-06 17:02:09

+0

我認爲他建議將新窗口的New或Load方法完成的工作放在新線程中。然後窗口可以打開並顯示一條加載消息(如果在加載事件中) – Mike 2011-04-06 17:02:57

2

你不 - 只有一個GUI線程。如果你需要做阻塞工作,那東西必須在後臺線程中。

2

您需要使用Application類在新線程中運行單獨的消息循環。

+1

正確答案,不好的建議。 – 2011-04-06 17:52:07

+0

@亨克:是的;我意識到這是不好的建議。但是,其他答案已經涵蓋了這一點。 – SLaks 2011-04-06 17:56:10

1

@SLaks如果您嘗試從控制檯應用程序啓動一個新窗口,這可能非常有用。一種選擇是使用showDialog();但是很難關閉它。

如果使用Show(),然後一個Application.run()(這是堅果和使用應用程序類,以啓動一個新的消息循環的螺栓)當您在主控制檯線程中調用Application.Exit()

,然後應用程序實際上關閉;

使用showDialog(),您必須中止該線程,然後等待窗口獲得某種輸入即鼠標懸停或焦點。否則它將永遠退出。

相關問題