首頁 >後端開發 >C++ >如何與`sync` lambdas與'parallel.foreach'正確使用?

如何與`sync` lambdas與'parallel.foreach'正確使用?

Patricia Arquette
Patricia Arquette原創
2025-02-01 03:16:08408瀏覽

How to Properly Use `async` Lambdas with `Parallel.ForEach`?

使用異步Lambda的並行ForEach

並行處理集合的一種方法是使用帶有Lambda表達式的Parallel.ForEach方法。但是,如果要在Lambda表達式中調用標記為異步的方法,則會遇到一些問題。

問題在於,Parallel.ForEach創建的線程只是後台線程,該方法不會等待它們的完成。您可以在以下示例中看到這一點:

<code class="language-csharp">var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
    // 预处理
    var response = await GetData(item);
    bag.Add(response);
    // 后处理
});
var count = bag.Count;</code>

問題在於,count 將為 0,因為對 Parallel.ForEach 的調用不會等待 Lambda 完成。如果刪除 async 關鍵字,則該方法如下所示:

<code class="language-csharp">var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
    // 预处理
    var responseTask = GetData(item); // 注意这里去掉了await
    responseTask.Wait();
    var response = responseTask.Result;
    bag.Add(response);
    // 后处理
});
var count = bag.Count;</code>

這種方法有效,但是它禁用了 await 的優勢,並且需要您進行手動異常處理。

如何實現使用異步Lambda的Parallel.ForEach

有兩種方法可以實現使用 await 關鍵字的 Parallel.ForEach 循環:

1. 簡單並行化

此方法很簡單,只需要幾行代碼:

<code class="language-csharp">var bag = new ConcurrentBag<object>();
var tasks = myCollection.Select(async item =>
{
    // 预处理
    var response = await GetData(item);
    bag.Add(response);
    // 后处理
});
await Task.WhenAll(tasks);
var count = bag.Count;</code>

2. 複雜並行化

此方法比較複雜,但可以更好地控制並行化過程。有關詳細信息,請查看 Stephen Toub 的 ForEachAsync 文章。

以上是如何與`sync` lambdas與'parallel.foreach'正確使用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn