Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Await in Main method - Who gets the control until Task is completed?

Await before an uncompleted Task will pass the control to the caller, until the Task is completed.

When you use it in Main() who is going to get the control?

public static async Task Main()
{
   await F1() ;   //This await will pass the control to ???           
}

public static async Task F1()
{
   await Task.Run(()=>{...}) ;   //This await will pass the control to Main()      
}
    
like image 804
S Itzik Avatar asked Dec 30 '22 21:12

S Itzik


1 Answers

The primary thread that keeps your app alive is effectively:

private static void TheRealEntryPoint() => Main().GetAwaiter().GetResult();

(which is broadly the same as .Wait(), and is the kind of "sync-over-async" thing that you should never write in your own code, but ... which suffices in this specific scenario)

As such:

  • the Task.Run returns an incomplete task
  • thus the await on that returns to the caller, taking us back to Main()
  • in an incomplete state, so that await also returns to the caller - so we end up in TheRealEntryPoint
  • where the primary thread simply blocks
  • ...
  • at some point, the thread-pool picks up the work item and runs it
  • marking the task as complete
  • which reactivates F1, which can now mark itself as complete
  • which reactivates Main, which can now mark itself as complete
  • which unblocks the primary thread that is stuck in TheRealEntryPoint
  • which allows the exe to terminate
like image 87
Marc Gravell Avatar answered Jan 13 '23 11:01

Marc Gravell