Bibi
Bibi

Reputation: 73

Unexpected async/await behaviour

Here is a program that mimics the flow of my real case scenario:

using System;
using System.Threading.Tasks;

namespace TestAsync
{
    interface IInterface
    {
        Task<int> DoSomething(int i);
    }

    class MyClass : IInterface
    {
        public async void MainAsync()
        {
            var i = 1;
            Console.WriteLine("Start MainAsync:" + i);
            var t = DoSomething(i);
            Console.WriteLine("After DoSomething: " + i );
            i = await t;
            Console.WriteLine("Done waiting: " + i);
        }

        public async Task<int> DoSomething(int i)
        {
            i = i + 1;
            Console.WriteLine("In Something:" + i);
            await Task.Delay(1000);
            Console.WriteLine("After Long Process: " + i);
            return i;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var m = new MyClass();
            m.MainAsync();
            Console.WriteLine("Main done.");
        }        
    }
}

The output I am getting is this:

Start MainAsync:1
In Something:2
After DoSomething: 1
Main done.
Press any key to continue . . .

This tells me that i = await t; is popping the process back up to Main and never comes back once done with the tasks.

What am I doing wrong?

I am looking for a result like:

Start MainAsync:1
In Something:2
After DoSomething: 1
After Long Process: 2
Done waiting: 2
Main done.
Press any key to continue . . .

or maybe

Start MainAsync:1
In Something:2
After DoSomething: 1
Main done.
After Long Process: 2
Done waiting: 2
Press any key to continue . . .

Thank you for your insight.

Upvotes: 1

Views: 246

Answers (1)

Servy
Servy

Reputation: 203802

Once the main method has completed you now no longer have any non-background threads running in your program, so the whole process will end. The fact that you have code that is going to eventually fire at some point in the future doesn't change that.

This is why you would normally have a message loop at the top level of your application, able to accept and process messages, and wait for more messages if there are currently none to process. Since the thread that is running the message pump would be a non-background thread, it wouldn't allow the process to end until the whole loop is closed.

Upvotes: 6

Related Questions