簡體   English   中英

Parallel.ForEach 與異步 lambda 等待所有迭代完成

[英]Parallel.ForEach with async lambda waiting forall iterations to complete

最近我看到了幾個與 Parallel.ForEach 相關的 SO 線程與異步 lambdas 混合,但所有建議的答案都是某種解決方法。

有什么辦法可以寫:

List<int> list = new List<int>[]();

Parallel.ForEach(arrayValues, async (item) =>
{
  var x = await LongRunningIoOperationAsync(item);
  list.Add(x);
});

如何確保列表將包含在每次迭代中使用 lambda 執行的所有迭代中的所有項目?

Parallel.ForEach 通常如何與異步 lambdas 一起工作,如果它命中等待,它會將其線程移交給下一次迭代嗎?

我認為 ParallelLoopResult IsCompleted 字段不正確,因為它會在執行所有迭代時返回 true,無論它們的實際 lambda 作業是否完成?

最近我看到了幾個與 Parallel.ForEach 相關的 SO 線程與異步 lambdas 混合,但所有建議的答案都是某種解決方法。

嗯,那是因為Parallel不適用於async 從不同的角度來看,您首先為什么要混合它們? 他們做相反的事情 Parallel就是添加線程, async就是放棄線程。 如果您想同時進行異步工作,請使用Task.WhenAll 這是完成這項工作的正確工具; Parallel不是。

也就是說,聽起來您想使用錯誤的工具,所以這是您的操作方法...

如何確保列表將包含在每次迭代中使用 lambda 執行的所有迭代中的所有項目?

您需要有某種信號,某些代碼可以在處理完成之前阻止該信號,例如, CountdownEventMonitor 附帶說明一下,您還需要保護對非線程安全List<T>

Parallel.ForEach 通常如何與異步 lambdas 一起工作,如果它命中等待,它會將其線程移交給下一次迭代嗎?

由於Parallel不理解async lambda,當第一個await產生(返回)給它的調用者時, Parallel將假定循環的交互已經完成。

我認為 ParallelLoopResult IsCompleted 字段不正確,因為它會在執行所有迭代時返回 true,無論它們的實際 lambda 作業是否完成?

正確的。 Parallel所知,它只能“看到”返回給調用者的第一個await的方法。 所以它不知道async lambda 何時完成。 它還會假設迭代過早完成,這會導致分區中斷。

你不需要Parallel.For/ForEach在這里你只需要等待任務列表。

背景

簡而言之,您需要非常小心異步 lambdas ,如果您將它們傳遞給ActionFunc<Task>

您的問題是因為Parallel.For / ForEach不適合async 和 await 模式IO 綁定任務 它們適用於受CPU 限制的工作負載 這意味着它們本質上具有Action參數,讓任務調度程序為您創建任務

如果你想同時運行多個異步任務,使用Task.WhenAll ,或者一個TPL 數據流(或類似的東西),它可以有效地處理CPU 綁定IO 綁定的工作負載,或者更直接地說,它們可以處理任務就是異步方法

除非您需要在 lambda 內部執行更多操作(您尚未顯示),否則只需使用SelectWhenAll

var tasks = items .Select(LongRunningIoOperationAsync);
var results = await Task.WhenAll(tasks); // here is your list of int

如果你這樣做,你仍然可以使用等待,

var tasks = items.Select(async (item) =>
   {
       var x = await LongRunningIoOperationAsync(item);
       // do other stuff
       return x;
   });

var results = await Task.WhenAll(tasks);

注意:如果您需要Parallel.ForEach的擴展功能(即控制最大並發的選項),有多種方法,但 RX 或 DataFlow 可能是最簡潔的

暫無
暫無

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

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