Result:
M1M2M2M1
Reason:
In the SomeEnd1 method, the M1 task is awaited before the M2 task has been called.
Suggestion:
In the SomeEnd2 method, both tasks are started before awaiting any to complete. Ideally you wouldn’t await each task individually, instead use await Task.WhenAll()… SomeEnd2 would be better like this:
public async Task SomeEnd2() { var tasks = new List<Task>(); tasks.Add(M1()); tasks.Add(M2()); await Task.WhenAll(tasks); }
The result will be the same, but this pattern will allow you to add tasks as needed without the need to await each individually.
Futher thoughts:
If you needed the result of one asynchronous method before starting another method, you can kick off all non-dependent tasks and then await the task(s) need for the dependent task(s) and still await Task.WhenAll(tasks) before you need the results.
Try the code below, I have added more output lines with some formatting that may help illustrate things a bit.
CAsync2 myc = new CAsync2();await myc.SomeEnd1();Console.WriteLine();Console.WriteLine();await myc.SomeEnd2();Console.WriteLine();Console.WriteLine();await myc.SomeEnd3();public class CAsync2{ public async Task<string> M1() { Console.WriteLine(" M1 start"); var value = Path.GetRandomFileName(); await Task.Delay(4000); Console.WriteLine(" M1 complete"); return value; } public async Task M2() { Console.WriteLine(" M2 start"); await Task.Delay(200); Console.WriteLine(" M2 complete"); } public Task M3(string value) { Console.WriteLine(" M3 start"); Console.WriteLine($" M3 - value = \"{value}\""); Console.WriteLine(" M3 complete"); return Task.CompletedTask; } public async Task SomeEnd1() { Console.WriteLine("SomeEnd1 start"); await M1(); await M2(); Console.WriteLine("SomeEnd1 complete"); } public async Task SomeEnd2() { Console.WriteLine("SomeEnd2 start"); var tasks = new List<Task>(); tasks.Add(M1()); tasks.Add(M2()); await Task.WhenAll(tasks); Console.WriteLine("SomeEnd2 complete"); } public async Task SomeEnd3() { Console.WriteLine("SomeEnd3 start"); var tasks = new List<Task>(); var m1 = M1(); tasks.Add(m1); tasks.Add(M2()); var m1Result = await m1; tasks.Add(M3(m1Result)); await Task.WhenAll(tasks); Console.WriteLine("SomeEnd3 complete"); }}
In fact, you don’t need to add the m1 Task to the task list since we are waiting for it to be completed before startng M3.