在Main方法中的Await - 任务完成前谁掌控权?

6

等待未完成的任务完成后,才将控制权交给调用者。

当您在Main()中使用它时,谁会获得控制权?

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()      
}
    

1
https://dev59.com/0FYO5IYBdhLWcg3wL-rY#0LajEYcBWogLw_1bFQYR - GSerg
1
@GSerg 你好,感谢您的评论,但是您提供的链接并没有回答我的问题。 - S Itzik
它确实是如此。它用简单的英语描述了相关的代码行,该行代码来自于 答案 下发布的内容。同样的一行代码现在也在下面的答案中重新发布了。 - GSerg
1个回答

11

让你的应用程序保持运行的主线程实际上是:

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

(这与 .Wait() 大致相同,并且是一种“同步/异步”操作,您不应该在自己的代码中编写,但对于特定场景而言足够使用)

因此:

  • Task.Run 返回一个未完成的任务
  • 因此await 返回到调用方,将我们带回到Main()
  • 处于未完成状态,所以 那个 await 也返回到调用方-因此我们最终进入了 TheRealEntryPoint
  • 主线程会简单地阻塞
  • ...
  • 在某个时间点,线程池会接收到工作项并运行它
  • 标记任务为已完成
  • 这激活了F1,现在可以将自己标记为已完成
  • 这再次激活了Main,现在可以将自己标记为已完成
  • 这解除了主线程在TheRealEntryPoint中被卡住的状态
  • 这使exe能够终止

TheRealEntryPoint()只是标准的Main()吗?这意味着线程会在标准Main()中被阻塞吗? - S Itzik
@SItzik 这是编译器发明的一种方法;名称并不重要,但它实际上不是 Main - 编译器可以将任何喜欢的东西标记为入口点。在本地测试中,它实际上被称为 <Main>()(带有尖括号),使其在常规 C# 中无法发音。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接