简体   繁体   English

使用Lambda表达式将Parallel.ForEach循环转换为并行任务

[英]Converting a Parallel.ForEach loop into parallel tasks using lambda expression

Need help converting this to a lamdba expression where I can use Task.WhenAll: 需要帮助将其转换为可以使用Task.WhenAll的lamdba表达式:

public void DoWork(string id)
{            
       var items = GetItems(id);  //takes time

       if (items == null)
       {
            return;
       }

       Parallel.ForEach(items, item =>
       {
            DoSomething(item); //takes time
            DoWork(item.subItemId);                    
       });           
}

I would like to change the Parallel For loop into tasks using a lambda expressions as suggested in Martin's answer in this thread: How to call an async method from within a loop without awaiting? 我想按照Lambda表达式中的建议在Lambda表达式中将Parallel For循环更改为任务: 如何在不等待的情况下从循环中调用异步方法?

Not sure how to specify the multiple line after item =>. 不知道如何在item =>之后指定多行。 This doesn't seem to work: 这似乎不起作用:

public void DoWork(string id)
{            
       var items = GetItems(id);  //takes time

       if (items == null)
       {
           return;
       } 

       var tasks = items.Select(item => 
       {
           DoSomething(item)
           DoWork(item.subItemId)
       });      

       await Task.WhenAll(tasks);         
}

UPDATE: 更新:

Thank you all for your answers. 谢谢大家的答案。 If I have an if condition, would I be wasting tasks? 如果我有一个if条件,我会浪费任务吗? Is there a better to code this? 有更好的编码吗? Do I need to be using Where instead? 我需要改用Where吗?

var tasks = items.Select(async item => 
{ 
    if (item.HasWork)
    {
       await DoSomethingAsync(item);
       await DoWorkAsync(item.subItemId);
    }
});      

await Task.WhenAll(tasks);  

It's easiest to use an async lambda: 使用async lambda最简单:

public async Task DoWorkAsync(string id)
{            
  var items = GetItems(id);  //takes time

  if (items == null)
    return;

  var tasks = items.Select(async item => 
  { 
    await DoSomethingAsync(item);
    await DoWorkAsync(item.subItemId);
  });      

  await Task.WhenAll(tasks);         
}

Martin's original answer assumes you'd write your own async method instead of an async lambda, which may make the code clearer: Martin的原始答案假设您将编写自己的async方法而不是async lambda,这可能会使代码更清晰:

public async Task DoWorkAsync(string id)
{            
  var items = GetItems(id);  //takes time

  if (items == null)
    return;

  var tasks = items.Select(item => ProcessAsync(item));

  await Task.WhenAll(tasks);         
}

private async Task ProcessAsync(T item)
{
  await DoSomethingAsync(item);
  await DoWorkAsync(item.subItemId);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM