C# – How to await in Main

You can await in the Main() method without needing to use Task.Run(). Just add async Task to the Main() method signature, like this:

static async Task Main(string[] args) { while (true) { Console.WriteLine("I'm looping"); await Task.Delay(5000); } }
Code language: C# (cs)

The Async Main feature was added in C# 7.1 and works with all overloads of Main(). It’s syntax sugar that compiles down to calling GetAwaiter().GetResult() on whatever you’re awaiting. In other words, it’s equivalent to doing the following (which you could do yourself in previous versions):

static void Main(string[] args) { while (true) { Console.WriteLine("I'm looping"); Task.Delay(5000).GetAwaiter().GetResult(); } }
Code language: C# (cs)

Await in a top-level statement

With the top-level statement feature (added in .NET 6), you can write programs without needing to explicitly define the Main() method. The compiler generates the right overload of Main() implicitly.

You can actually await in a top-level statement without doing anything special. Just add ‘await’ and the compiler will automatically generate the right async overload of Main() implicitly.

Here’s an example of awaiting in a top-level statement:

//Program entry point while (true) { Console.WriteLine("I'm looping"); await Task.Delay(5000); }
Code language: C# (cs)

This is equivalent to the async Task Main() code shown in the section above. The difference is that the Main() method is implicitly defined by the compiler.

Task.Run() in Main

You can use Task.Run() in the Main() method. How you do this depends on exactly what you’re trying to accomplish. This is related to awaiting in Main(), but not exactly the same. Here’s an example of firing off two async lambdas with Task.Run():

static void Main(string[] args) { Task.Run(async () => { while (true) { Console.WriteLine($"I'm looping 1. Thread id = {Thread.CurrentThread.ManagedThreadId}"); await Task.Delay(2000); } }); Task.Run(async () => { while (true) { Console.WriteLine($"I'm looping 2. Thread id = {Thread.CurrentThread.ManagedThreadId}"); await Task.Delay(2000); } }); Console.Read(); }
Code language: C# (cs)

This runs these two loops concurrently and outputs the following after a few seconds:

I'm looping 1. Thread id = 6 I'm looping 2. Thread id = 7 I'm looping 2. Thread id = 6 I'm looping 1. Thread id = 4 I'm looping 1. Thread id = 7 I'm looping 2. Thread id = 4
Code language: plaintext (plaintext)

Leave a Comment