I am learning async methods in C#, and I am trying to create a small program that calls few methods in sequence with a small delay. at the end of the operation, I am calculating the total time elapsed. Here is my code.
public static async Task<string> MakeCoffeeAsync() { Thread.Sleep(3000); return("Coffee is Ready"); } public static async Task<string> ToastBreadAsync() { Thread.Sleep(2000); return ("Bread is Toasted"); } public static async Task<string> ApplyJamToBreadAsync() { Thread.Sleep(1000); return ("Jam added to Bread"); } public static async void MakeBreakfast() { Console.WriteLine("Making Breakfast async way"); Stopwatch sw = new Stopwatch(); sw.Start(); Console.WriteLine(await MakeCoffeeAsync()); Console.WriteLine(await ToastBreadAsync()); Console.WriteLine(await ApplyJamToBreadAsync()); sw.Stop(); Console.WriteLine("Normal Way - Total Time Taken " + sw.ElapsedMilliseconds / 1000 + " Seconds"); } This is working correctly and I am getting 6 Seconds as output which is correct.
Now I want two tasks to start simultaneously. One Task can start making the coffee (This will take 3 seconds), and second task will Start the Toast (This will take 2 seconds) and Once the toast is ready, the second task will apply Jam to the already toasted bread (This will take 1 second). The sequence is important for Toast. The Jam should only be applied after the Toast is ready.
Expected output : Total elapsed time should be 3 seconds. Because coffee and (Toast + Jam) will run parallelly.
This is what I have tried.
public static async void MakeBreakfastConcurrent() { Console.WriteLine("Making Breakfast Concurrent way"); Stopwatch sw = new Stopwatch(); sw.Start(); await Task.Run(() => Console.WriteLine(MakeCoffeeAsync())); await Task.Run(() => { Console.WriteLine(ToastBreadAsync()); Console.WriteLine(ApplyJamToBreadAsync()); }); sw.Stop(); Console.WriteLine("Normal Way - Total Time Taken " + sw.ElapsedMilliseconds / 1000 + " Seconds"); } But this is not working as expected. When I run this, nothing prints after "Making Breakfast Concurrent way"
What am I doing wrong, and how to achieve the correct execution order in concurrent way? (probably something like .then() in JS ?)
Thread.Sleepdoes not do what you think it does. (Anyway, generally speaking, no-one should be usingThread.Sleepanyway).await Task.Delay()instead ofThread.Sleep()async/awaitdoes not imply concurrency at all - instead,async/awaitis an alternative syntax for defining a continuation state-machine - everything else (concurrency, threading, synchronization, etc) is a runtime concern (e.g. using the Thread Pool, or using a custom scheduler, etc. 2.Thread.Sleepblocks a thread entirely which defeats the point of usingawaitbecause the thread itself is blocked and so can't await itself.Thread.Sleepsimulates a blocking call, whereasasync/await(andTask-returning asynchronous APIs in general in .NET) are intended for non-blocking calls. There is no reason to (and plenty of reasons against) usingasync/awaitwith calls to blocking methods (i.e. blocking calls).