2013-05-02 91 views
2
  1. 我有兩個UI線程,一個是主線程,另一個是後臺線程,其ApartmentState是STA。每個線程創建自己的窗口,並且背景窗口上有一個「取消」按鈕。WPF中的多線程UI

  2. 主線程有一個繁忙的功能,需要很長時間才能完成。我希望一旦點擊「取消」按鈕,主線程應該停止耗時的功能。

  3. 下面是僞代碼在主線程:

    的(...) {

    //Option A: Application.DoEvents(); 
        //Option B: Dispatcher.Invoke to update UI in background thread 
        if(cancel)  
        return; //Stop the time-consuming function 
        else  
        DoSomething; 
    

    }

奇怪的是,點擊事件「取消」按鈕不被後臺線程捕獲或處理。國際海事組織,每個線程都有自己的消息隊列,當我點擊「取消」按鈕時,這個消息應該排隊和後臺線程立即處理,但根據我的測試本地,這是不正確的,後臺線程永遠不會處理按鈕點擊事件...

有什麼想法?

順便說一句,我認爲有兩種方法可以解決上述問題,一種是使用Application.DoEvents,另一種是利用Dispatcher.Invoke。但我仍然很好奇爲什麼後臺線程無法立即處理消息。提前致謝。

+2

'Application.DoEvents'在WPF中不存在...你是如何實現它的? – 2013-05-02 15:48:24

+0

做。事件。 lawd。 – Will 2013-05-02 15:56:09

回答

3

一般來說,擁有兩個用戶界面線程往往是一個壞主意,而且完全沒有必要。

您通常只有一個用戶界面線程,只是將實際的計算工作移動到後臺線程中。用戶界面更新將根據需要編組回主線程。 BackgroundWorker很適合在很多情況下使用。

至於取消,通常最好使用圍繞CancellationTokenSourceCancellationToken構建的框架cooperative cancelation model進行處理。這些設計可以跨多個線程使用,並自動處理所需的適當內存屏障。

+0

謝謝里德。是的,我知道有兩個UI線程是不好的......但爲什麼後臺線程無法處理按鈕單擊事件,以及爲什麼Application.DoEvents可以工作? – buaaji 2013-05-02 16:00:08

+0

@buaaji您可能在調用時使用錯誤的調度程序... – 2013-05-02 16:01:55