2013-05-02 89 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