具有异步 lambda 的并行 foreach [英] Parallel foreach with asynchronous lambda

查看:47
本文介绍了具有异步 lambda 的并行 foreach的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想并行处理一个集合,但我在实现它时遇到了麻烦,因此我希望得到一些帮助.

I would like to handle a collection in parallel, but I'm having trouble implementing it and I'm therefore hoping for some help.

如果我想在并行循环的 lambda 内调用 C# 中标记为 async 的方法,就会出现问题.例如:

The trouble arises if I want to call a method marked async in C#, within the lambda of the parallel loop. For example:

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 关键字,则该方法如下所示:

The problem occurs with the count being 0, because all the threads created are effectively just background threads and the Parallel.ForEach call doesn't wait for completion. If I remove the async keyword, the method looks like this:

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;

它有效,但它完全禁用了等待智能,我必须进行一些手动异常处理..(为简洁起见已删除).

It works, but it completely disables the await cleverness and I have to do some manual exception handling.. (Removed for brevity).

如何实现在 lambda 中使用 await 关键字的 Parallel.ForEach 循环?可能吗?

How can I implement a Parallel.ForEach loop, that uses the await keyword within the lambda? Is it possible?

Parallel.ForEach 方法的原型采用 Action 作为参数,但我希望它等待我的异步 lambda.

The prototype of the Parallel.ForEach method takes an Action<T> as parameter, but I want it to wait for my asynchronous lambda.

推荐答案

如果你只是想要简单的并行,你可以这样做:

If you just want simple parallelism, you can do this:

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 发帖.

If you need something more complex, check out Stephen Toub's ForEachAsync post.

这篇关于具有异步 lambda 的并行 foreach的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆