0

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

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(...); 
    } 
    } 
} 

回答

0

如果你的后台线程调用阻塞你的UI(通过Control.Invoke),然后你的UI线程被阻塞调用您的止损方法,其thread.Join()你拥有属于自己的经典致命的拥抱。你应该摆脱Join,而是在后台线程在Stop完成时引发最后一个事件/通知,以便UI可以处理(启用/禁用按钮等)。

+0

你的意思是我应该在UpdateView函数的末尾设置一些事件(cancelledEvent)并将thread.Join替换为cancelledEvent.WaitOne?但是WaitOne也会阻止该线程。有什么区别吗? – wince

+0

你**不能做的是在UI线程中调用Thread.Join。你可以删除那一个电话,并罚款。但我认为这是因为UI想知道(等待)后台处理程序的完成。如果您需要该功能,请让后台处理程序在退出之前发送另一个通知。您不显示您的编组代码,但考虑使用BeginInvoke进行此调用,以便您的后台处理程序不会等待通知被处理。 – tcarvin

+0

实际上,我的'view.UpdateUI'函数调用'Invoke(...)'方法,我已经将'BeginInvoke(...)'和'thread.Join'替换为'canceledEvent.WaitOne'。现在好像还好,谢谢。 – wince