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

lmc*_*iro 8 c# .net-core asp.net-core

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

有很多方法可以开始使用该应用程序Microsoft.Extensions.Hosting接口IHostIHostBuilder.

我知道使用asyncvs 之间的区别sync,但所有这些选项之间有什么区别?使用Runvs Start和呼叫IHostBuildervs呼叫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>();
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

gre*_*mac 18

针对 .NET Core 3.1 进行了更新。

概括

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

方法

启动异步

Task IHost.StartAsync(CancellationToken cancellationToken = default);
Run Code Online (Sandbox Code Playgroud)

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

开始

void Start(this IHost host);
Run Code Online (Sandbox Code Playgroud)

同步包装器 IHost.StartAync();

运行异步

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

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

等待关机异步

Task WaitForShutdownAsync(this IHost host, CancellationToken token = default)
Run Code Online (Sandbox Code Playgroud)

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

等待关机

void WaitForShutdown(this IHost host)
Run Code Online (Sandbox Code Playgroud)

同步包装器 IHost.WaitForShutdownAync();

停止异步

Task IHost.StopAsync(CancellationToken cancellationToken = default)
Run Code Online (Sandbox Code Playgroud)

优雅地停止主机,返回主机停止后完成的任务。取消cancellationToken表示停止不再优雅。

还有一个扩展方法允许传递 aTimeout代替:

public static Task StopAsync(this IHost host, TimeSpan timeout)
    => host.StopAsync(new CancellationTokenSource(timeout).Token);
Run Code Online (Sandbox Code Playgroud)


Ale*_*bov 12

// 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;
}
Run Code Online (Sandbox Code Playgroud)

// 3 - 在主机上调用Run(sync/async)

RunAsync运行应用程序并返回在触发取消令牌或关闭时完成的任务.同步只是一个包装:

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

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

这个方法实际上是启动程序,最终从任何其他方式调用它.