跟着兔子洞一起去吧。
IHostedService
的实例由异步方法HostedServiceExecutor.StartAsync()
调用(HostedServiceExecutor源代码)。
WebHost.StartAsync()
是异步调用HostedServiceExecutor.StartAsync()
的(WebHost源代码)。
WebHost
实现了IWebHost
,其中Start
和StartAsync
均有同步和异步版本。但是,WebHost.Start()
的实现只调用了异步版本:
public void Start()
{
StartAsync().GetAwaiter().GetResult();
}
最后,WebHost.Start()
被 Program.Main
调用(由默认的 ASP.NET Core 项目模板生成):
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
通过这些调用链,我们可以继续回答你的问题:“为什么 IHostedService
是异步的?”并得到“为什么 IWebHost
是异步的?”或者“为什么 C# 7 引入了异步的 Main()
方法?”的答案。
您可以从以下讨论中了解到原因:
那么,主要原因是简化从程序根部调用异步方法。通常程序流程需要调用异步方法(无论是自己实现的还是第三方库的)。
以旧方法为例,我们需要这样做:
public static void Main(string[] args)
{
SomeAsyncCall().GetAwaiter().GetResult();
}
现在,我们可以使用一种清晰的方式将其全部异步化:
static async Task Main(string[] args)
{
await SomeAsyncCall();
}
IHostedService.StartAsync()
也适用于同样的情况。在主机服务准备期间可能需要调用一些异步操作。关于主机服务概念的
这个讨论明确说明了这一点:
StartAsync方法是异步的,因为我们可能需要执行一些准备任务,如果执行失败就会影响初始化。
希望这回答了您的问题。
如果您正在寻找有关适当实现
IHostedService
的文档,这里是一个很好的选择:
在ASP.NET Core 2.0中实现IHostedService。
BackgroundService.StartAsync
在_executingTask
正在运行时返回Task.CompletedTask
- 因为否则整个Web应用程序的启动将会被延迟。 - ironstone13