这些在ASP.NET Core中启动/运行通用主机的方式有什么区别?

53

ASP.NET Core中的托管设计现在有一个新的通用主机(.NET Core 2.1+),将来将取代Web主机。

使用Microsoft.Extensions.Hosting接口的IHostIHostBuilder有多种启动应用程序的方法。

我知道使用asyncsync之间的区别,但所有这些选项之间有什么区别?使用RunStart以及在IHostBuilder上调用还是在IHost上调用?

请参见下面代码中的选项// 1// 2// 3//4

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyNamespace
{
    class Program
    {
        static async Task Main(string[] args)
        {
            IHostBuilder builder = CreateBuilder();

            // 1 - Call Run on the builder (async)
            await builder.RunConsoleAsync();    // extension method

            // 2 - Call Start on the builder (sync)
            builder.Start();                    // extension method

            IHost host = builder.Build();       // Call Build on the builder to get a host

            // 3 - Call Run on the host (sync / async)
            host.Run();                         // extension method
            await host.RunAsync();              // extension method

            // 4 - Call Start on the host (sync / async)
            host.Start();                       // extension method
            await host.StartAsync();            // class method
        }

        private static IHostBuilder CreateBuilder() => new HostBuilder()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                //...
            })
            .ConfigureLogging((hostingContext, logging) => {
                //...
            })
            .ConfigureServices((hostContext, services) =>
            {
                //...
                services.AddSingleton<IHostedService, MyService>();
            });
    }
}
2个回答

52

已更新至 .NET 6。

概述

  • 除了 RunConsoleAsync 方法外,所有这些方法都作用于一个 IHost 实例。在 IHostBuilder 上的这些方法只是调用了 IHost.Build(),然后委托给 IHost 的方法(例如,IHostBuilder.StartAsync() 等效于 IHostBuilder.Build().StartAsync())。
  • Start 方法启动主机并立即返回
  • Run 方法启动主机,并等待其完成后再返回
  • 同步版本仅是实际异步实现的包装器(.GetAwaiter().GetResult())。

方法

StartAsync

Task IHost.StartAsync(CancellationToken cancellationToken = default)

启动主机(Web 应用程序)。任务完成后,主机已启动。

开始

void Start(this IHost host)

同步封装到IHost.StartAsync的方法。

RunAsync

Task RunAsync(this IHost host, CancellationToken token = default)
{
    using (host)
    {
        await host.StartAsync(token);
        await host.WaitForShutdownAsync(token);
    }
}

启动主机。任务完成时,主机关闭,可以通过取消令牌或在另一个线程上调用StopAsync()来触发关闭。

WaitForShutdownAsync

Task WaitForShutdownAsync(this IHost host, CancellationToken token = default)

返回一个任务,当应用程序关闭时完成。通过传递的令牌启动关闭,并取消令牌会导致应用程序停止。

WaitForShutdown

void WaitForShutdown(this IHost host)

同步包装器,用于 IHost.WaitForShutdownAsync

StopAsync

Task IHost.StopAsync(CancellationToken cancellationToken = default)

优雅地停止主机,返回一项任务,在主机停止后完成。取消 cancellationToken 表示不再需要优雅地停止。

还有一个扩展方法允许传递 Timeout

public static Task StopAsync(this IHost host, TimeSpan timeout)
    => host.StopAsync(new CancellationTokenSource(timeout).Token);

RunConsoleAsync

:运行控制台异步操作。
Task RunConsoleAsync(this IHostBuilder hostBuilder, CancellationToken cancellationToken = default)
    => hostBuilder.UseConsoleLifetime().Build().RunAsync(cancellationToken);

源代码

这是唯一使用 IHostBuilder (而不是 IHost)的方法,因为它调用了UseConsoleLifetime() (需要 IHostBuilder)。这也会导致等待 Ctrl+C 退出。

此外,没有相应的Start方法,我只能揣测这是因为在控制台应用程序中,绝大多数情况下,这是您所需的全部内容。 非常少数运行其他后端服务和 ASP.NET 的应用程序可能最好使用 RunAsync() 并自己管理生命周期(即控制 CancellationToken)。


3
RunConsoleAsync() 怎么样? - Pang

31

// 1 - 调用生成器的 Run 方法(异步)

RunConsoleAsync 启用控制台支持,构建并启动主机,并等待 Ctrl+C/SIGINT 或 SIGTERM 来关闭。所以正如其名称所示,它仅适用于在控制台中托管您的应用程序(而非 IIS 等)。

// 2 - 调用生成器的 Start 方法(同步)

只是同步地启动主机。

public static IHost Start(this IHostBuilder hostBuilder)
{
    var host = hostBuilder.Build();
    host.StartAsync(CancellationToken.None).GetAwaiter().GetResult();
    return host;
}

// 3 - 在主机上调用Run(同步/异步)

RunAsync运行应用程序并返回一个任务,当取消标记或关闭触发时完成。同步只是一个包装:

public static void Run(this IHost host)
{
    host.RunAsync().GetAwaiter().GetResult();
}

// 4 - 在主机上调用Start(同步/异步)

该方法实际上是启动程序,最终可以从任何其他方式调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接