What is the difference between a regular foreach and ForEach LINQ operator when it comes to async/await

Viewed 486

Here are three versions of same(?) functionality

Version 1:

public async Task SomeMethodAsync(List<string> foos)
{
    foreach(var foo in foos)
    {
        await SomeOtherMethodAsync();
    }
    DoSomethingElse();
}

Version 2:

public void SomeMethod(List<string> foos)
{
    foos.ForEach(async foo => await SomeOtherMethodAsync());
    DoSomethingElse();
}

Version 3:

public async Task SomeMethod(List<string> foos)
{
    var tasks = foos.Select(foo => SomeOtherMethodAsync());
    await Task.WhenAll(tasks);
    DoSomethingElse();
}
  1. Why does this first version require the method to be marked async to use await inside the foreach loop vs the second version which doesn't need to be marked async (just the Lambda needs to be async).

  2. Does the second version wait for all the async/await calls inside the loop to complete before SomeMethod exits? I ask this because SomeMethod() is not async and it will not be awaited by it's caller.

  3. Is the third version the preferred way over versions 1 & 2?

1 Answers
Related