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

查看:157
本文介绍了带有异步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<T>作为参数,但我希望它等待我的异步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天全站免登陆