2015-09-15 139 views
1

我有一個BackgroundWorker偶爾需要調用UI線程來執行一些工作並檢索結果。要做到這一點,我使用下面的從後臺線程中:在WPF UI線程中等待Dispatcher.Invoke

App.Current.Dispatcher.Invoke(new Action(() => { /* some code that updates local data */ }); 

由於應用程序正在退出,我希望能夠告訴BackgroundWorker戒菸,但我想讓它完成任何當前操作。換句話說,我想呼叫BackgroundWorkerObj.CancelAsync(),然後抽出消息,直到線程退出。

我試過以下,但在後臺線程還是塊Invoke()(雖然UI線程仍在翻騰):

Worker.CancelAsync(); 
while (Worker.IsBusy) 
{ 
    DispatcherFrame Frame = new DispatcherFrame(); 
    Frame.Continue = false; 
    Dispatcher.PushFrame(Frame); 
} 

什麼是做到這一點的正確方法是什麼?在仍然執行BackgroundWorker對象的Invokes時,UI線程如何等待BackgroundWorker

+0

您正在開發什麼.NET Framework版本? – Sievajet

+0

目前4.0,但我可以去4.5,如果它在這種情況下會有所幫助。 –

+0

這是一個有保證的僵局,你不能等待。 [這篇文章](http://stackoverflow.com/a/1732361/17034)適用於WPF以及調整。讓工作線程像這樣調用應該總是可以避免的。 –

回答

1

這種關閉死鎖正是您爲什麼不應該爲此使用Invoke的原因。

將其更改爲BeginInvoke(),並用於返回工作線程的通信使用事件。

0

我會使用Task.Run,​​因爲你在.NET 4.0上。但無論如何。你必須以相反的方式去做。等待後臺工作完成,然後退出應用程序。在保持主線程響應的同時,無法等待後臺線程在關閉事件中完成。這個while循環會阻塞主線程和消息泵,直到後臺線程完成。

試試這個

private BackgroundWorker _worker;

protected override OnFormClosing(object sender , FormClosingEventArgs e) 
{ 
    base.OnFormClosing(sender , e); 

    // Cancel's the closing and keeps the form alive 
    e.Cancel = _worker.IsBusy; 
} 

private void RunWorkerCompleted(object sender , RunWorkerCompletedEventArgs e) 
{ 
    // Work is done, so close the form 
    Close(); 
}