为什么IHostedService是异步的

时间:2018-03-15 22:46:17

标签: .net asynchronous asp.net-core .net-core .net-core-2.0

我知道这是一个设计问题,但我试图理解这一点,以最好的方式使用它。因此,请考虑这个问题,以澄清它如何与其最强大的功能一起使用。

为什么它没有设计基于KISS的同步并且具有异步方法(StartAsyncStopAsync),AFAIK,Web请求中Async的主要好处是让一些空闲线程被释放为用于提供进一步的请求,但IHostedService不是这种情况,因为没有请求的概念,并且总有一个正在运行(或暂停)的线程。

1 个答案:

答案 0 :(得分:5)

让我们走下兔子洞。

IHostedService的实例由HostedServiceExecutor.StartAsync()调用,这是异步的(HostedServiceExecutor source code)。

<{>} HostedServiceExecutor.StartAsync()WebHost.StartAsync()调用,它是异步的(WebHost source code)。

WebHost实现IWebHost,其中包含同步和异步版本的开头:StartStartAsync。但是WebHost.Start()实现只调用异步版本:

public void Start()
{
    StartAsync().GetAwaiter().GetResult();
}

最后WebHost.Start()Program.Main调用(默认情况下为ASP.NET Core项目模板生成):

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

有了这个电话链,我们可以继续你的问题&#34;为什么IHostedService是异步的?&#34;并获得&#34;为什么IWebHost是异步的?&#34;或&#34;为什么c#7引入了异步Main()方法?&#34;。

您可以通过以下讨论获得推理:

嗯,主要原因是从程序root简化对异步方法的调用。通常,程序流需要调用异步方法(您自己的实现或第三方库)。 我们采用旧方法做了类似的事情:

public static void Main(string[] args)
{
    SomeAsyncCall().GetAwaiter().GetResult();
}

但是现在我们可以以干净的方式让它一直异步:

static async Task Main(string[] args)
{
    await SomeAsyncCall();
}

同样适用于IHostedService.StartAsync()。它可能需要在主机服务准备期间调用一些异步操作。 This discussion主机服务概念有一个明确的声明:

  

StartAsync方法是异步的,因为我们可能需要执行   可能无法执行的作业的一些准备任务   妥协初始化。

希望这能回答你的问题。

如果您正在寻找有关正确实施IHostedService的文档,请参阅以下内容:Implementing IHostedService in ASP.NET Core 2.0