Skip to content

Async main C# 7.1code reduction

Use `async` and `await` directly in `Program.Main`.

C# 5's async and await made asynchronous programming much simpler than before with the elimination of callbacks and method chains.

One omission however was the lack of support for Program.Main() to be async thus forcing console programs to be a little more convoluted in order to be able to use the many async operations now available in the .NET Framework.

C# 7.1 solves this by allowing Program.Main() to be async just like any other method with the compiler taking care of any necessary work behind the scenes.

Code ​

csharp
class Program
{
    static async Task<int> Main(string[] args)
    {
        try
        {
            var text = await File.ReadAllTextAsync(args[0]);
            Console.WriteLine(text);
            return 0;
        }
        catch(Exception ex)
        {
            Console.Error.WriteLine(ex);
            return -1;
        }
    }
}
csharp
class Program
{
    static int Main(string[] args)
    {
        return MainAsync(args).GetAwaiter().GetResult();
    }

    static async Task<int> MainAsync(string[] args)
    {
        try
        {
            var text = await File.ReadAllTextAsync(args[0]);
            Console.WriteLine(text);
            return 0;
        }
        catch(Exception ex)
        {
            Console.Error.WriteLine(ex);
            return -1;
        }
    }
}

Notes ​

  • The compiler generates a synchronous entry point that calls your Main and blocks with GetAwaiter().GetResult(), much like the "Before" code
  • An async Main must return Task or Task<int>; async void Main is not allowed
  • Libraries such as Nito.AsyncEx offered AsyncContext.Run as an alternative that also provided a single-threaded synchronization context

More information ​

Powered by Intracia