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

时间:2018-09-19 19:29:53

标签: c# asp.net-core .net-core

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 个答案:

答案 0 :(得分:8)

已针对.NET Core 3.1更新。

摘要

  • 启动方法启动服务,然后返回
  • 运行方法启动服务,然后等待其停止后再返回
  • 同步版本都只是实际异步实现(.GetAwaiter().GetResult();)的包装

方法

StartAsync

Task IHost.StartAsync(CancellationToken cancellationToken = default);

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

开始

void Start(this IHost host);

IHost.StartAync();的同步包装

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.WaitForShutdownAync();的同步包装

StopAsync

Task IHost.StopAsync(CancellationToken cancellationToken = default)

正常停止主机,并在主机停止后返回完成的任务。取消cancellationToken表示停止应该不再是正常情况。

还有一个扩展方法,它允许改为传递Timeout

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

答案 1 :(得分:7)

  

// 1-在构建器上调用“运行”(异步)

RunConsoleAsync启用控制台支持,构建并启动主机,并等待Ctrl + C / SIGINT或SIGTERM关闭。因此,正如其名称所期望的那样,它仅用于在控制台中托管您的应用程序(而不是IIS等)

  

// 2-在构建器上调用“启动”(同步)

只是同步启动主机

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-在主机上调用启动(同步/异步)

此方法实际上是在启动程序,最终可以通过其他任何方式调用。