【问题标题】:Thread synchronization in WinCEWinCE中的线程同步
【发布时间】:2013-02-04 11:58:22
【问题描述】:

我遇到了线程同步的问题。我的演示者分析了一些传感器并更新了 UI 表单。我将更新代码移动到单独的线程中。它工作正常,但是如果用户在更新视图时停止演示者,软件就会冻结 - 我发现它发生在 view.UpdateUI 工作时(它只是使用 Invoke 设置了一些标签)。我的问题在哪里?我使用紧凑型框架 3.5 和 Windows CE 5

using System.Threading;

class MyPresenter
{
  UserControl view;

  private Thread thread;
  private ManualResetEvent cancelEvent;

  public void Start()
  {
    cancelEvent = new ManualResetEvent(false);
    thread = new Thread(UpdateView) { IsBackground = true };
    thread.Start();
  }

  public void Stop()
  {
    if (thread != null) {
      cancelEvent.Set();
      thread.Join();
      thread = null;
    }
  }

  private void UpdateView()
  {
    while (cancelEvent.WaitOne(1000, false) == false) {
      // analyze something
      view.UpdateUI(...);
    }
  }
}

【问题讨论】:

    标签: c# winforms compact-framework windows-ce thread-synchronization


    【解决方案1】:

    不要直接从工作线程中更新 UI 线程。请改用委托。 例如:How to update the GUI from another thread in C#?

    【讨论】:

      【解决方案2】:

      如果您的后台线程被阻止调用您的 UI(通过 Control.Invoke),然后您的 UI 线程被阻止使用其 thread.Join() 调用您的 Stop 方法,那么您将获得一个经典的致命拥抱。您应该摆脱加入,而是让后台线程在停止完成时引发最后一个事件/通知,以便 UI 可以处理该问题(启用/禁用按钮等)。

      【讨论】:

      • 你的意思是我应该在UpdateView函数的末尾设置一些事件(cancelledEvent)并将thread.Join替换为cancelledEvent.WaitOne?但是 WaitOne 也会阻塞线程。有什么区别吗?
      • 不能做的是在 UI 线程中调用 Thread.Join。你可以去掉那个电话就没事了。但我认为它存在的原因是因为 UI 想知道(等待)后台处理程序的完成。如果您需要该功能,请让后台处理程序在它退出之前发送另一个通知。您不显示编组代码,但考虑使用 BeginInvoke 进行此调用,这样后台处理程序就不会等待处理通知。
      • 实际上我的 view.UpdateUI 函数称为 Invoke(...) 方法,我已将其替换为 BeginInvoke(...)thread.JoincanceledEvent.WaitOne。现在好像可以了,谢谢。
      猜你喜欢
      • 2023-03-22
      • 2014-04-30
      • 1970-01-01
      • 2013-04-01
      • 2012-03-20
      • 2011-02-01
      • 2019-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多