2014-01-24 15 views
10

背景在WPF應用程序中執行任務

private void Start(object sender, RoutedEventArgs e) 
{ 
    int progress = 0; 
    for (;;) 
    { 
     System.Threading.Thread.Sleep(1); 
     progress++; 
     Logger.Info(progress); 
    } 
} 

什麼是推薦的方法(TAP或TPL或BackgroundWorker的或調度員或其他人)如果我要開始()

  1. 不會阻塞UI螺紋
  2. 可以提供進度報告
  3. 可以取消
  4. 支持多線程和多核
+1

http://www.codeproject.com/Articles/58836/Using-Background-Process-in-WPF –

+1

可能的重複[如何在wpf背景中執行任務,同時能夠提供報告並允許取消?](http://stackoverflow.com/questions/21348125/how-to-execute-task-in-the-wpf-background-while-able-to-provide-report-and-allow) –

回答

17

在.NET 4.5(或.NET 4.0 + Microsoft.Bcl.Async),最好的方法是使用基於Task API和async/await。它允許使用方便的(僞)順序代碼工作流並具有結構化的異常處理。

實施例:

private async void Start(object sender, RoutedEventArgs e) 
{ 
    try 
    { 
     await Task.Run(() => 
     { 
      int progress = 0; 
      for (; ;) 
      { 
       System.Threading.Thread.Sleep(1); 
       progress++; 
       Logger.Info(progress); 
      } 
     }); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

更多讀數:

Async in 4.5: Enabling Progress and Cancellation in Async APIs

Async and Await

Async/Await FAQ

+0

如果我使用基於任務的API,我可以使用多線程和多核心嗎?順便說一句,BackgroundWorker能夠執行calcellation和進度報告。 BackgroundWorker和基於任務的API之間有什麼區別? –

+1

@publicENEMY,''基於任務'的API使'BackgroundWorker'廢棄,閱讀:[Task.Run vs BackgroundWorker](http://blog.stephencleary.com/search/label/Task.Run%20vs%20BgroundgroundWorker)。 'Task.Run'使用'ThreadPool'線程來運行你的任務,所以是的,它肯定支持多線程和多核。有一些學習曲線,但非常值得。 – Noseratio

+1

@publicENEMY不用擔心多個內核。操作系統將線程分配給內核(稱爲_processor affinity_),並嘗試使用所有內核(如果可以的話)!如果深入鑽取,任何異步編程方法都會使用'Thread's。 – Gusdor

1

您可以使用BackgroundWorker類在WPF中的單獨線程上執行操作。

檢查這個例子How to use WPF Background Worker

閱讀一些關於MSDN上的類此 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

+0

我完全忘了BackgroundWorker 。我的印象是BackgroundWorker適用於Winform,而WPF相當於Dispatcher類。順便說一下,AFAIK BackgroundWorker不支持多線程。如我錯了請糾正我。 –

+1

「創建多線程應用程序的最可靠方法是使用BackgroundWorker組件。該類管理一個單獨的線程,專用於處理您指定的方法。」來自http://msdn.microsoft.com/zh-cn/library /ck8bc5c6.aspx – StackTrace

+1

@publicENEMY background worker是用於運行異步操作和報告進度的助手類您可以在winforms和wpf中使用它,因爲'SynchronizationContext'機制對於兩者都是一致的。每個winforms對象封裝了一個'WindowsFormsSynchronizationContext'實例(允許訪問UI線程),但WPF將_actual消息pump_公開爲'Dispatcher' /這包含一個DispatcherSynchronizationContext。 – Gusdor

3

要做到這一點,最好的辦法是使用BackgroundWorker

我指出這個問題的原因是它專門設計用於在後臺處理工作,同時保持UI線程可用和響應。它還內置了Progress通知並支持Cancellation

我建議看幾個例子的BackgroundWorker

現在,當您開始查看後臺工作人員時,您需要深入瞭解一點Cancellation。設置後臺工作者的取消屬性不會取消後臺工作人員,這隻會引發一個標誌,讓您的運行方法定期進行互訪並正常停止處理。

這裏是我的文章前一段時間談取消後臺工作https://stackoverflow.com/a/20941072/1397504

最後的一個。異步並不意味着多核甚至多線程。 (WIKI

+0

您對BackgroundWorker支持取消和進度報告是正確的。謝謝。 –

相關問題