与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的ForEachAsyncpost 。

您可以使用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;