我想并行处理一个集合,但是我在实现它时遇到了麻烦,因此我希望得到一些帮助 .
如果我想在并行循环的lambda中调用C#中标记为async的方法,则会出现问题 . 例如:
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;
计数为0时会出现问题,因为创建的所有线程实际上只是后台线程, 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;
它工作,但它完全禁用等待聪明,我必须做一些手动异常处理..(为简洁起见删除) .
如何在lambda中使用await关键字实现 Parallel.ForEach
循环?可能吗?
Parallel.ForEach方法的原型采用 Action<T>
作为参数,但我希望它等待我的异步lambda .
4 回答
您可以使用AsyncEnumerator NuGet Package中的
ParallelForEachAsync
扩展方法:如果您只想要简单的并行性,可以这样做:
如果您需要更复杂的东西,请查看Stephen Toub's ForEachAsync post .
我已经为此创建了一个扩展方法,它使用了SemaphoreSlim,并且还允许设置最大并行度
样品用法:
我的ParallelForEach异步的轻量级实现 .
特征:
限制(最大并行度) .
异常处理(完成时将抛出聚合异常) .
内存高效(无需存储任务列表) .
用法示例: