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
Mainand blocks withGetAwaiter().GetResult(), much like the "Before" code - An async
Mainmust returnTaskorTask<int>;async void Mainis not allowed - Libraries such as Nito.AsyncEx offered
AsyncContext.Runas an alternative that also provided a single-threaded synchronization context