与asynchronouslambda平行的foreach
我想同时处理一个集合,但是我在执行时遇到了麻烦,所以我希望得到一些帮助。
如果我想在并行循环的lambda中调用C#中标记为asynchronous的方法,则会出现问题。 例如:
var bag = new ConcurrentBag<object>(); Parallel.ForEach(myCollection, async item => { // some pre stuff var response = await GetData(item); bag.Add(response); // some post stuff } var count = bag.Count;
问题发生在count为0时,因为所有创build的线程都只是后台线程,并且Parallel.ForEach
调用不会等待完成。 如果我删除了async关键字,方法如下所示:
var bag = new ConcurrentBag<object>(); Parallel.ForEach(myCollection, item => { // some pre stuff var responseTask = await GetData(item); responseTask.Wait(); var response = responseTask.Result; bag.Add(response); // some post stuff } var count = bag.Count;
它的工作,但它完全禁用了等待的聪明,我不得不做一些手动exception处理..(为简洁起见,删除)。
我如何实现一个在lambda中使用await关键字的Parallel.ForEach
循环? 可能吗?
Parallel.ForEach方法的原型需要一个Action<T>
作为参数,但我希望它等待我的asynchronouslambda。
如果你只是想要简单的并行性,你可以这样做:
var bag = new ConcurrentBag<object>(); var tasks = myCollection.Select(async item => { // some pre stuff var response = await GetData(item); bag.Add(response); // some post stuff }); await Task.WhenAll(tasks); var count = bag.Count;
如果您需要更复杂的东西,请查看Stephen Toub的ForEachAsync
post 。
您可以使用AsyncEnumerator NuGet包中的ParallelForEachAsync
扩展方法:
using System.Collections.Async; var bag = new ConcurrentBag<object>(); await myCollection.ParallelForEachAsync(async item => { // some pre stuff var response = await GetData(item); bag.Add(response); // some post stuff }, maxDegreeOfParallelism: 10); var count = bag.Count;