SpiritBob
SpiritBob

Reputation: 2662

When will awaiting a method exit the program?

I've been reading the following post, specifically this point:

On your application’s entry point method, e.g. Main. When you await an instance that’s not yet completed, execution returns to the caller of the method. In the case of Main, this would return out of Main, effectively ending the program.

I've been trying to do that, but I can't seem to make it exit. Here's the code I have:

class Program
{
    // ending main!!!
    static async Task Main(string[] args)
    {
        Task<Task<string>> t = new Task<Task<string>>(async () =>
        {
            Console.WriteLine("Synchronous");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Synchronous");
                Console.WriteLine("Synchronous I is: " + i);
                await Task.Run(() => { Console.WriteLine("Asynchronous"); });
                await Task.Run(() => { for (int j = 0; j < 1000; j++) { Console.WriteLine( "Asynchronous, program should have exited by now?"); }});
            }
            return "ASD";
        });
        t.Start();
        await t;
    }
}

What exactly am I missing here? Shouldn't the program exit upon hitting the line await t; or by following through the thread at await Task.Run(() => { Console.WriteLine("Asynchronous"); });?

This is a Console application's main method.

Upvotes: 1

Views: 360

Answers (1)

Matthew Watson
Matthew Watson

Reputation: 109557

The article you linked is from 2012, which predates the addition of async support to Main(), which is why what it's talking about seems wrong.

For the current implementation, consider the following code:

public static async Task Main()
{
    Console.WriteLine("Awaiting");
    await Task.Delay(2000);
    Console.WriteLine("Awaited");
}

This gets converted by the compiler as follows (I used "JustDecompile" to decompile this):

private static void <Main>()
{
    Program.Main().GetAwaiter().GetResult();
}

public static async Task Main()
{
    Console.WriteLine("Awaiting");
    await Task.Delay(2000);
    Console.WriteLine("Awaited");
}

Now you can see why the program doesn't exit.

The async Task Main() gets called from static void <Main>() which waits for the Task returned from async Task Main() to complete (by accessing .GetResult()) before the program exits.

Upvotes: 3

Related Questions