2012-12-18 71 views
7

我已閱讀Ansyc/Await的'BackgroundWorker'爲designed to be replaced是否等待使該方法的其餘部分異步?

因爲我喜歡Async/Await的濃縮外觀,我開始將一些BackgroundWorkers轉換爲Async/Await調用。

這是代碼我有(從UI調用)的例子:

public async void RunFromTheUI() 
{ 
    await OtherAction(); 
} 

public async void OtherAction() 
{ 
    var results = await services.SomeRemoteAction(); 

    foreach (var result in results) 
    { 
     result.SemiIntenseCalculation(); 
     Several(); 
     Other(); 
     NonAsync(); 
     Calls(); 
    } 

    SomeFileIO(); 
} 

當我打電話RunFromTheUI它幾乎立即返回(按照異步並等待設計)。

但是當它在services.SomeRemoteAction()完成後繼續時,它有一個foreach循環和另一個方法調用來運行。

我的問題是:如果這個循環是性能豬,它會凍結UI嗎?(之前我把它全部放在後臺工作線程中,所以它沒有減慢UI)。

注意:我的目標是.Net 4.0並使用Async Nuget Package。

+0

async/await和BackgroundWorker解決了兩個不同的問題。 BG工作人員更精確地被任務取代。當工作人員身體代碼基本閒置時,Async只會取代這些代碼,當您需要執行繁重工作時,BGW /任務仍然有用。我看起來像你在等待服務結果的問題,只是供參考。 –

+0

1.你的代碼不會編譯,你不能'等待''async void'方法。 2.你應該避免使用'async void'方法,它們不能'等待'並且使異常處理更加困難。 – svick

回答

6

我的問題是:如果該循環是一個性能豬會凍結用戶界面?

是的,它會的。異步方法的其餘部分仍將在遠程操作完成時在UI線程上執行。如果你不希望這種情況發生,則該選項是:

  • 使用ConfigureAwait(continueOnCapturedContext: false)使延續執行UI線程
  • 上執行整個方法在不同的線程首先,使用Task.Run。 (你仍然可以使它成爲一種異步方法,以避免在你不需要時阻塞線程)。

基本上,如果你有負載的同步,阻塞調用或CPU密集型工作,你希望避免這種情況發生在UI線程上,這與async/await默認爲你做的相反。

+1

如果使用'async','Task.Run'的默認值會比'Task.Factory.StartNew'更好。 [斯蒂芬Toub進入細節。](http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx) –

+0

@StephenCleary:修正,謝謝。我沒有注意 - 當然,'Task.StartNew'無效,當然:) –

+0

喬恩:任何好的起點讀/理解異步/等待,任務? – shahkalpesh