.net - 为什么 IHostedService 是异步的

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

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

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

最佳答案

我们去兔子洞吧。
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();
}

有了这个调用链,我们可以继续你的问题“为什么 IHostedService 是异步的?”并得到“为什么 IWebHost 是异步的?”或“为什么 c# 7 引入了异步 Main() 方法?”。

您可以从以下讨论中得到推理:
  • What is the point of having async Main?
  • Proposal: Add Async support for Main() / Console Apps
  • C# 7 Series, Part 2: Async 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/

    相关文章:

    .net - .Net Nest中的ElasticSearch过滤器聚合

    c# - Visual Studio 2005 : List<T>. C# 中的 First() List<T>.Last() 方法?

    .net - RazorEngine - 如果仅在 View 中使用,则不会加载引用的程序集

    Azure.Security.KeyVault.Secrets : az is not recognized as an internal or external command

    c# - 如何将一串位转换为字节数组

    asynchronous - Angular 2 的异步加载路由数据和构建路由指令

    c# - 具有异步操作的 ASP.NET MVC

    javascript - socket.io 和异步事件

    c# - ASP.NET MVC Core 应用程序中的实时通知

    c# - <FrameworkReference Include ="Microsoft.AspNetCore.App"/> 在.net core 3+ 中实际上是做什么的?