IWebHost:调用 运行() 与 运行Async()
IWebHost: Calling Run() vs RunAsync()
创建新的 ASP.NET Core 2.0 项目时,Program
class 中的样板 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);
}
According to the documentation,Run
方法:
Runs a web application and block the calling thread until host shutdown.
而 RunAsync
方法:
Runs a web application and returns a Task that only completes when the token is triggered or shutdown is triggered.
我想知道什么时候应该使用 RunAsync
方法而不是常规的 Run
方法?这有什么实际意义?最终用户会注意到任何不同吗?
What are the practical implications of this? Would the end-user notice
any difference?
运行时级别行为没有区别。
Since this feature does not correspond to a CLR code change, the async
Main method is just a syntactical sugar. This design allows backend
compatibility with the previous versions of the language. To read more
details, please see Async Main in the Roslyn Git repo.
- C# 7
Series, Part 2: Async Main
默认 ASP.NET 核心模板包含以下 Main
方法:
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
那个Run
方法就是WebHostExtensions.Run
extension method which is implemented like this:
public static void Run(this IWebHost host)
{
host.RunAsync().GetAwaiter().GetResult();
}
所以这实际上调用了 WebHostExtensions.RunAsync
,只是阻塞了它。
现在,让我们看看 C# 7.1 的异步 Main
方法 is specified:
When one of [these task-based methods] is identified as the entrypoint, the compiler will synthesize an actual entrypoint method that calls one of these coded methods:
static Task Main()
will result in the compiler emitting the equivalent of private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
static Task Main(string[])
will result in the compiler emitting the equivalent of 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 核心应用程序的生命周期内进行设置工作(即在 Startup
中,而不是在它之外)。
创建新的 ASP.NET Core 2.0 项目时,Program
class 中的样板 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);
}
According to the documentation,Run
方法:
Runs a web application and block the calling thread until host shutdown.
而 RunAsync
方法:
Runs a web application and returns a Task that only completes when the token is triggered or shutdown is triggered.
我想知道什么时候应该使用 RunAsync
方法而不是常规的 Run
方法?这有什么实际意义?最终用户会注意到任何不同吗?
What are the practical implications of this? Would the end-user notice any difference?
运行时级别行为没有区别。
Since this feature does not correspond to a CLR code change, the async Main method is just a syntactical sugar. This design allows backend compatibility with the previous versions of the language. To read more details, please see Async Main in the Roslyn Git repo.
- C# 7 Series, Part 2: Async Main
默认 ASP.NET 核心模板包含以下 Main
方法:
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
那个Run
方法就是WebHostExtensions.Run
extension method which is implemented like this:
public static void Run(this IWebHost host)
{
host.RunAsync().GetAwaiter().GetResult();
}
所以这实际上调用了 WebHostExtensions.RunAsync
,只是阻塞了它。
现在,让我们看看 C# 7.1 的异步 Main
方法 is specified:
When one of [these task-based methods] is identified as the entrypoint, the compiler will synthesize an actual entrypoint method that calls one of these coded methods:
static Task Main()
will result in the compiler emitting the equivalent ofprivate static void $GeneratedMain() => Main().GetAwaiter().GetResult();
static Task Main(string[])
will result in the compiler emitting the equivalent ofprivate 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 核心应用程序的生命周期内进行设置工作(即在 Startup
中,而不是在它之外)。