2012-12-12 86 views
3

我正在設計一個多線程的進程,其中我創建了一個線程來執行一些處理,以便不鎖定用戶界面。然而,當這個線程完成時(如果它成功完成了W/O錯誤),我需要一個事件,所以我可以在UI線程上執行一個方法,以正確更新用戶界面。多線程問題 - 線程完成後需要的事件

我該如何正確實現這個目標?

我的主題簡單的代碼:

Thread t = new Thread(new ThreadStart(GetAppUpdates)); 
t.Start(); 

現在我需要的線程完成時就知道了,但我覺得我不希望執行代碼,將不斷檢查線程的狀態,因爲它會導致UI延遲。

(我知道使用backgroundworker會更容易,但我不想爲此過程設置背景工作,因爲此線程不能爲背景)。

當Thread對象完成時,是否有辦法觸發事件?完成ThreadFinished()事件的最佳方式是什麼?線程成功完成後,我必須在主UI上執行代碼。

+0

爲什麼你需要它不會是一個後臺線程,如果你已經有了一個UI起來:這可以通過一個延續做些什麼呢?這將阻止終止進程...無論如何,我會建議使用'Task'而不是'BackgroundWorker' ... –

+0

BackgroundWorker是爲此設計的。 「不能成爲背景」是什麼意思?後臺線程與另一個線程相同。 –

+0

@JonSkeet我的理解是,background = true或backgroundworker線程不會導致應用程序在關閉之前等待。用戶可以隨時關閉應用程序,但我需要所有線程處理完成才能關閉。 – Encryption

回答

4

通過新的匿名方法,它調用GetAppUpdates()和其他一些方法,它通知你有關獲取更新完成:後您的GetAppUpdates()方法將被執行

Thread t = new Thread(new ThreadStart(() => { GetAppUpdates(); Completed(); })); 
t.Start(); 

Completed方法將被調用:

private void Completed() 
{ 
    if (InvokeRequired) 
    { 
     Invoke((MethodInvoker)delegate() { Completed(); }); 
     return; 
    } 

    // update UI 
} 

BTW這將完成這項工作,但我最好與BackgroundWorker一起使用 - 它是爲這樣的任務設計的,它是RunWorkerComple特德事件處理程序將在UI線程上運行,這非常方便。

+0

啊有趣的...所以在調用該方法的調用後我再次UI安全? – Encryption

+0

@加密完全相同,這就是爲什麼我們有'InvokeRequired'屬性和'Invoke'方法:) –

+0

尼斯...打敗調用每個UI控件的調用 – Encryption

0

我會推薦使用Task而不是線程來寫這個。由於您在完成時更新UI,因此您需要確保它在UI線程中運行。

Task task = Task.Factory.StartNew(() => GetAppUpdates()); 
task.ContinueWith(t => UpdateUserInterface(), 
        TaskScheduler.FromCurrentSynchronizationContext()); 
+0

僅僅是.Net 4.0嗎?我卡住了3。5 – Encryption

+0

@Encryption yes,.Net 4.0上可用的任務 –

+0

@Encryption如果您安裝舊版本的Rx Extensions(其中包含TPL的回送端口),則可以在3.5中使用它, –