Hello
Hello

Reputation: 816

async await code executing not as expected

I created a simple example to understand async/await in C#.

class Program
{
    static void Main(string[] args)
    {
        var t = BarAsync();
        Console.WriteLine("Main");
    }

    private static async Task BarAsync()
    {
        Console.WriteLine("This happens before await");
        int i = await QuxAsync();
        Console.WriteLine("This happens after await. This result of await is " + i);
    }

    private static Task<int> QuxAsync()
    {
        int c = 0;
        for (int i = 0; i < int.MaxValue; i++)
        {
            c++;
        }
        Console.WriteLine("in the middle processing...");
        return Task.FromResult(c);
    }
}

So the program prints This happens before await first then count the value from a return method. Afterwards it prints the result.

image

It looks good. My question is that since await doesn't block the thread that evaluates the async method. My understanding is if the async takes a long time it will return to its calling method.

For my example, because QuxAsync() takes a long time, the code

Console.WriteLine("Main");

is not blocked and will be evaluated very soon. I think the print order should be

 This happens before await
 Main
 in the middle processing...
 This happens after await. This result of await is 2147483647

However it is not, why?

Upvotes: 2

Views: 146

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 457157

I'll second (third?) others' recommendations that you continue reading and learning about async. I'm partial to my own async intro, but these days there are a number of good ones out there.

My question is that since await doesn't block the thread that evaluates the async method. My understanding is if the async takes a long time it will return to its calling method.

This is the part that is wrong. Asynchrony has absolutely nothing to do with how long something takes.

There's two pieces of knowledge missing, both covered in my async intro.

First: await works by first checking its argument. If it is already completed, then await continues executing - synchronously.

Second: every method is called synchronously. Including async methods. The only time asynchrony happens is when an async method has an await whose argument is not already completed; in that case, that async method returns an incomplete task.

Putting both of these together should explain why your code actually runs synchronously.

Upvotes: 2

Related Questions