Home > Back-end >  Async and await - having trouble understanding
Async and await - having trouble understanding

Time:09-17

I've tried reading through some of the Microsoft support but i am trying to simply it down as i find most of it confusing. I dont understand why the remainder of the method gets executed? It looks like as soon as it hits an await it jumps out then never returns, why wont it come back in and start from where it left? I'm trying to get the program to jump out while coffee is waiting and ten start on the eggs, so to have them perform asynchronously. Any help appreciated - thanks.

 class Program
{
    static async Task Main(string[] args)
    { 
        Stopwatch stopWatch = new Stopwatch();
        Task<Coffee> coffeeTask = MakeCoffeeAsync(stopWatch);           
        Task<Egg> eggTask = FryEggs(2);
        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;
        string elapsedTime = String.Format("{0:00}", ts.Seconds);
        Console.WriteLine("Time to make breakfast: "   elapsedTime   " seconds");
    }                

    private static async Task<Egg> FryEggs(int howMany)
    {
        Console.WriteLine("Warming the egg pan...");
        await Task.Delay(3000);
        Console.WriteLine($"cracking {howMany} eggs");
        Console.WriteLine("cooking the eggs ...");
     //  await Task.Delay(8000);
        Console.WriteLine("Put eggs on plate");
        Console.WriteLine("eggs are ready");
        return new Egg();
    }

    private static async Task<Coffee> MakeCoffeeAsync(Stopwatch timerstart)
    {
        timerstart.Start();
        Console.WriteLine("Turning on machine");
        Console.WriteLine("Waiting on machine to be ready");
        await Task.Delay(5000);
        Console.WriteLine("Getting cup");
       // await Task.Delay(4000);
        Console.WriteLine("weighing beans");
        Console.WriteLine("tamping coffee");
       // await Task.Delay(8000);
        Console.WriteLine("pouring coffee into cup");
        Console.WriteLine("coffee is ready"   "\n");
        return new Coffee();
    }
}
class Egg { }
class Coffee { }

This is the output:

Waiting on machine to be ready
Warming the egg pan...
Time to make breakfast: 00 seconds

CodePudding user response:

You can wait for all task to be execute:

await Task.WhenAll(eggTask, coffeeTask);

static async Task Main(string[] args)
{ 
    Stopwatch stopWatch = new Stopwatch();
    Task<Coffee> coffeeTask = MakeCoffeeAsync(stopWatch);           
    Task<Egg> eggTask = FryEggs(2);
    await Task.WhenAll(eggTask, coffeeTask);// NOTE THIS
    stopWatch.Stop();
    TimeSpan ts = stopWatch.Elapsed;
    string elapsedTime = String.Format("{0:00}", ts.Seconds);
    Console.WriteLine("Time to make breakfast: "   elapsedTime   " seconds");
} 

Another options is adding await keyword:

static async Task Main(string[] args)
{ 
    Stopwatch stopWatch = new Stopwatch();
    Coffee coffeeTask = await MakeCoffeeAsync(stopWatch);           
    Egg eggTask = await FryEggs(2);
    stopWatch.Stop();
    TimeSpan ts = stopWatch.Elapsed;
    string elapsedTime = String.Format("{0:00}", ts.Seconds);
    Console.WriteLine("Time to make breakfast: "   elapsedTime   " seconds");
} 

CodePudding user response:

Async methods return a task, which can have different states: the task might be still operating or it might be finished. If you add an await, the program will wait until the task is finished. Because you don't have an await, your program doesn't wait until your breakfast is finished.

static async Task Main(string[] args)
    { 
        Stopwatch stopWatch = new Stopwatch();
        Task<Coffee> coffeeTask = MakeCoffeeAsync(stopWatch);           
        Task<Egg> eggTask = FryEggs(2);
        Coffee cofee = await cofeeTask;
        Egg egg = await eggTask;
        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;
        string elapsedTime = String.Format("{0:00}", ts.Seconds);
        Console.WriteLine("Time to make breakfast: "   elapsedTime   " seconds");
    } 

CodePudding user response:

You're firing/forgetting your tasks. You should await them to avoid exiting the program prior to finishing the execution:

    static async Task Main(string[] args)
    { 
        Stopwatch stopWatch = new Stopwatch();
        Task<Coffee> coffeeTask = MakeCoffeeAsync(stopWatch);           
        Task<Egg> eggTask = FryEggs(2);
        Coffee coffee = await coffeeTask;
        Egg egg = await eggTask;
        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;
        string elapsedTime = String.Format("{0:00}", ts.Seconds);
        Console.WriteLine("Time to make breakfast: "   elapsedTime   " seconds");
    }

CodePudding user response:

The reason your flow is never returning is because you have not awaited the functions FryEggs and MakeCoffeeAsync.

await is the keyword that tells your code to stop here until it has results.

If you want to make coffee and eggs at the same time, you want to await FryEggs.

If you want to make coffee, then make eggs, you want to await both FryEggs and MakeCoffeeAsync

  • Related