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