Reputation: 13325
Need help converting this to a lamdba expression where I can use Task.WhenAll:
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?
Not sure how to specify the multiple line after 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? Is there a better to code this? Do I need to be using Where instead?
var tasks = items.Select(async item =>
{
if (item.HasWork)
{
await DoSomethingAsync(item);
await DoWorkAsync(item.subItemId);
}
});
await Task.WhenAll(tasks);
Upvotes: 0
Views: 1749
Reputation: 456342
It's easiest to use an 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:
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);
}
Upvotes: 7