Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Not able to call asynchronous methods in correct order concurrently in C#

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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 ?)

>Solution :

Your methods are not asynchronous. You should have gotten a compiler warning. A method is only asynchronous, if at least one of its statements contains the await keyword. The async keyword in your method delcaration alone doesn’t make your method asynchronous! To make your methods asynchronous, replace Thread.Sleep by await Task.Delay:

public static async Task<string> MakeCoffeeAsync()
{
    await Task.Delay(3000);
    return("Coffee is Ready");           
}

public static async Task<string> ToastBreadAsync()
{
    await Task.Delay(2000);
    return ("Bread is Toasted");
}

public static async Task<string> ApplyJamToBreadAsync()
{
    await Task.Delay(1000);
    return ("Jam added to Bread");
}

To run your methods concurrently, first call the methods without awaiting them. Then await all tasks and print the results:

Task<string> coffeTask = MakeCoffeeAsync();
Task<string> breadTask = ToastBreadAsync();
Task<string> jamTask = ApplyJamToBreadAsync();

await Task.WhenAll(coffeeTask, breadTask, jamTask);

string coffeeResult = await coffeTask;
string breadResult = await breadTask;
string jamResult = await jamTask;
Console.WriteLine(coffeeResult);
Console.WriteLine(breadResult );
Console.WriteLine(jamResult );

Online-demo: https://dotnetfiddle.net/vhJLtk

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading