IWebHost: Calling Run() vs RunAsync()



创建新的 ASP.NET Core 2.0项目时,Program类中的样板Main方法如下所示:

public static void Main(string[] args)
{
BuildWebHost(args).Run(); // BuildWebHost returns an IWebHost
}

但从 C# 7.1 开始,Main方法可以是返回Task而不是void的异步方法。这意味着在Main中调用异步方法要容易得多。

因此,可以在Main内部调用IWebHost上的RunAsync(),而不是Run()方法。像这样:

public static async Task Main(string[] args)
{
await BuildWebHost(args).RunAsync().ConfigureAwait(false);
}

根据文档,Run方法:

运行 Web 应用程序并阻止调用线程,直到主机关闭。

RunAsync方法:

运行 Web 应用程序并返回仅在触发令牌或触发关闭时完成的任务。

我想知道什么时候应该使用RunAsync方法而不是常规Run方法?这有什么实际意义?最终用户会注意到任何差异吗?

默认 ASP.NET 核心模板包含以下Main方法:

public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

Run方法,WebHostExtensions.Run扩展方法,其实现方式如下:

public static void Run(this IWebHost host)
{
host.RunAsync().GetAwaiter().GetResult();
}

所以这实际上调用了WebHostExtensions.RunAsync,并且只是阻止它。


现在,让我们看一下如何指定 C# 7.1 的异步Main方法:

当其中一个[这些基于任务的方法]被标识为入口点时,编译器将合成一个实际的入口点方法,该方法调用以下编码方法之一:

  • static Task Main()将导致编译器发出等效的private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task Main(string[])将导致编译器发出等效的private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();

所以基本上,有一个异步Main方法,如下所示:

public static async Task Main(string[] args)
{
await BuildWebHost(args).RunAsync();
}

将导致编译器还发出以下内容:

private static void $GeneratedMain(string[] args)
{
Main(args).GetAwaiter().GetResult();
}

如果你仔细观察那里返回的任务会发生什么,这几乎与WebHostExtensions.Run方法完全相同。

这是什么意思呢?您可以使用这些解决方案中的任何一种,效果将是相同的。应用程序将正确阻止,直到异步任务得到解决。解决方案之间没有实际区别。使用异步 main 方法的唯一真正好处是,如果您在Main方法中有其他异步工作要做;尽管这种情况可能非常罕见,因为对于 Web 应用程序,您更有可能在 ASP.NET Core 应用程序的生命周期内(即在Startup中而不是在它之外)进行设置工作。

这有什么

实际意义?最终用户会注意到吗 有什么区别吗?

运行时级别行为没有区别。

由于此功能不对应于 CLR 代码更改,因此异步 主要方法只是一个语法糖。此设计允许后端 与该语言的先前版本的兼容性。阅读更多 有关详细信息,请参阅 Roslyn Git 存储库中的异步主。
- C# 7 系列,第 2 部分:异步主

相关内容

  • 没有找到相关文章

最新更新