async at console app in C#?

Royi Namir picture Royi Namir · Jul 13, 2013 · Viewed 118.8k times · Source

I have this simple code :

public static async Task<int> SumTwoOperationsAsync()
{
    var firstTask = GetOperationOneAsync();
    var secondTask = GetOperationTwoAsync();
    return await firstTask + await secondTask;
}


private async Task<int> GetOperationOneAsync()
{
    await Task.Delay(500); // Just to simulate an operation taking time
    return 10;
}

private async Task<int> GetOperationTwoAsync()
{
    await Task.Delay(100); // Just to simulate an operation taking time
    return 5;
}

Great. this compiles.

But Lets say I have a console app and I want to run the code above ( calling SumTwoOperationsAsync())

 static  void Main(string[] args)
        {
             SumTwoOperationsAsync();
        }

But I've read that (when using sync) I have to sync all the way up and down :

Question : So does this means that my Main function should be marked as async ?

Well it can't be because there is a compilation error:

an entry point cannot be marked with the 'async' modifier

If I understand the async stuff , the thread will enter the Main function ----> SumTwoOperationsAsync ---->will call both functions and will be out. but until the SumTwoOperationsAsync

What am I missing ?

Answer

Stephen Cleary picture Stephen Cleary · Jul 13, 2013

In most project types, your async "up" and "down" will end at an async void event handler or returning a Task to your framework.

However, Console apps do not support this.

You can either just do a Wait on the returned task:

static void Main()
{
  MainAsync().Wait();
  // or, if you want to avoid exceptions being wrapped into AggregateException:
  //  MainAsync().GetAwaiter().GetResult();
}

static async Task MainAsync()
{
  ...
}

or you can use your own context like the one I wrote:

static void Main()
{
  AsyncContext.Run(() => MainAsync());
}

static async Task MainAsync()
{
  ...
}

More information for async Console apps is on my blog.