We came across a bug in our product and reduced it to the following problem. Given a list and call to the ForEach-Extension method with an async lambda, what is the expected order of the output:
public static async Task Main()
{
var strings = new List<string> { "B", "C", "D" };
Console.WriteLine("A");
strings.ForEach(async s => { await AsyncMethod(s); } );
Console.WriteLine("E");
}
private static async Task AsyncMethod(string s)
{
await Task.Run(() => { Console.WriteLine(s); });
}
We expected it to be always A,B,C,D,E. But sometimes it's A,B,C,E,D or A,B,E,D,C
We thought that these two lines would be equivalent:
strings.ForEach(async s => { await AsyncMethod(s); });
foreach (var s in strings) await AsyncMethod(s);
Can somebody explain where the difference is? How are these async lambdas executed and why are they not awaited?
Clarification: The problem is not the order of B,C and D. The problem is that E comes before the loop is finished