我知道这是一个设计问题,但我试图理解这一点以最好的方式使用它。因此,请将此问题视为对如何使用其最大功能的澄清。
为什么它没有设计基于 KISS 的同步和异步方法( StartAsync
, StopAsync
),AFAIK,Async 在 web 请求中的主要好处是让一些空闲线程被释放用于服务进一步的请求,但它IHostedService
不可能是这种情况因为没有请求的概念,并且总是有一个正在运行(或挂起)的线程。
最佳答案
我们去兔子洞吧。IHostedService
的实例由 HostedServiceExecutor.StartAsync()
调用这是异步的( HostedServiceExecutor source code )。HostedServiceExecutor.StartAsync()
由 WebHost.StartAsync()
调用这是异步的( WebHost source code )。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()
方法?”。您可以从以下讨论中得到推理:
嗯,主要原因是简化从程序根调用异步方法。通常程序流需要调用异步方法(您自己的实现或第 3 方库)。
使用旧方法,我们要做这样的事情:
public static void Main(string[] args)
{
SomeAsyncCall().GetAwaiter().GetResult();
}
但是现在我们可以以一种干净的方式让它一直异步:
static async Task Main(string[] args)
{
await SomeAsyncCall();
}
这同样适用于
IHostedService.StartAsync()
.它可能需要在主机服务准备期间调用一些异步操作。 This discussion主机服务概念对此有明确的声明:The StartAsync method is asynchronous because we may need to execute some preparation tasks for the job that may fail to execute and compromise the initialization.
希望这能回答你的问题。
如果您正在寻找有关正确实现
IHostedService
的文档,这是一个很好的:Implementing IHostedService in ASP.NET Core 2.0
关于.net - 为什么 IHostedService 是异步的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49310446/