2
  1. 我有两个 UI 线程,一个是主线程,另一个是后台线程,其 ApartmentState 为 STA。每个线程创建自己的窗口,后台窗口上有一个“取消”按钮。

  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;
    

    }

奇怪的是,“取消”按钮上的点击事件没有被后台线程捕获或处理。IMO,每个线程都有自己的消息队列,当我单击“取消”按钮时,该消息应该立即由后台线程排队并处理,但根据我在本地的测试,这是不正确的,后台线程永远不会处理按钮点击事件...

有什么想法吗?

BTW,我认为有两种方法可以克服上述问题,一种是使用Application.DoEvents,另一种是利用Dispatcher.Invoke。但我仍然很好奇为什么后台线程不能立即处理消息。提前致谢。

4

1 回答 1

3

一般来说,拥有两个用户界面线程通常是个坏主意,而且完全没有必要。

您通常只有一个用户界面线程,只需将实际的计算工作移至后台线程即可。用户界面更新将根据需要编组回主线程。 BackgroundWorker在许多情况下非常适合这个。

至于取消,通常最好使用围绕和构建的框架合作取消模型来处理。这些设计考虑了跨多个线程的使用,并自动处理所需的适当内存屏障。CancellationTokenSourceCancellationToken

于 2013-05-02T15:50:05.423 回答