簡體   English   中英

使用異步等待或任務?

[英]Use async await or task?

您已經構建了一個復雜的計算算法。 這需要相當長的時間才能完成,並且您希望確保應用程序保持響應。 你是做什么?

  • A.使用async / await。
  • B.同步運行代碼。
  • C.使用Task.Run。
  • D.使用BackgroundWorker。

答案是C.但是,有人可以解釋為什么A)不正確嗎? 因為問題並不是說復雜的算法是CPU綁定的。 如果它是CPU綁定的,那么我們將不得不使用任務(一種我不太了解的推理,但我知道任務確實有助於導致當前線程被掛起直到它們完成)。 另外,請解釋如何決定何時使用async / await,並使用Tasks。

你是做什么?

A.使用async / await。

B.同步運行代碼。

C.使用Task.Run。

D.使用BackgroundWorker。

實現了C#5.0中的async/await功能,以使異步代碼“像編寫同步代碼一樣簡單”。 如果你研究WinAPI,你會發現幾乎所有的異步端點都暴露了一個完全異步的api,這意味着沒有線程 進一步看,您會注意到那些相同的端點正在進行I / O綁定操作。

假設您的算法是CPU綁定的 ,並且以允許跨多個處理器進行有效計算的方式編寫(例如,您的算法沒有任何需要同步的共享狀態),您可以利用中介紹的任務並行庫 。 NET 4.0。 TPL提供了對ThreadPool的抽象,而ThreadPool又試圖在多處理器環境中均勻地卸載工作。

await關鍵字可用於任何等待對象,這意味着該對象實現了GetAwaiter方法。 當你正在使用await時,你會希望使用await ,並且當等待完成它的工作時,希望執行恢復。 Task實現了等待模式,用於描述將在未來完成的工作單元。 當您想要卸載工作線程上的工作單元並且希望將控制權返回給調用方法時,您可以使用Task.Runawait直到完成該工作

在多個處理器之間調度CPU綁定工作的另一種方法是使用Parallel類,它暴露Parallel.ForParallel.ForEach

在旁注中, BackgroundWorker也可用於卸載后台線程上的工作,如果這就是提出問題的人所追求的內容。 自.NET 4.0發布以來, 建議使用TPL。

總而言之,使用任務並行庫是將工作卸載到后台線程的推薦方法。 您可以將它們與Parallel庫結合使用,以最大化算法的並行性。 執行此操作后,請測試您的代碼以確保使用多個線程的開銷不會超過同步運行算法所需的時間。

編輯

正如Stephan在評論中提到的,您可以將Parallel.ForEachTask.Run結合起來卸載后台線程中的並行循環:

var task = Task.Run(() => Parallel.ForEach(.. //Loop here));

我認為“計算”意味着在沒有其他信息的情況下CPU綁定算法。 如果算法是IO綁定async / await不僅可以接受,而且是正確的答案。

我相信這個問題假定你有一個同步編程的算法。 這個問題提到它是一個“計算”,模糊地暗示它是受CPU限制的。 它也非常模糊地暗示算法是同步編寫的。 例如:

public int CalculateStuff() {
     ....
}

我要考慮的是創建這個方法的異步對應物:

public async Task<int> CalculateStuffAsync() {
      return await Task.Run(() => CalculateStuff());
}

然后在您的用戶界面中:

LoadingIndicator.IsEnabled = true;
ResultTextBox.Text = await CalculateStuffAsync();
LoadingIndicator.IsEnabled = false;

因此,正確的答案可能是A和C.無論如何,這個問題太模糊,無法得出任何可靠的結論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM