.NET 通用主机.NET Generic Host

作者:Luke LathamBy Luke Latham

ASP.NET Core 应用配置和启动主机。ASP.NET Core apps configure and launch a host. 主机负责应用程序启动和生存期管理。The host is responsible for app startup and lifetime management.

本文介绍 .NET Core 泛型主机 (HostBuilder)。This article covers the .NET Core Generic Host (HostBuilder).

泛型主机与 Web 主机的不同之处在于它将 HTTP 管道与 Web 主机 API 分离,以启用更广泛的主机方案。Generic Host differs from Web Host in that it decouples the HTTP pipeline from the Web Host API to enable a wider array of host scenarios. 消息、后台任务和其他非 HTTP 工作负载可以使用泛型主机并从横切功能(如配置、依赖关系注入 [DI] 和日志记录)中受益。Messaging, background tasks, and other non-HTTP workloads can use Generic Host and benefit from cross-cutting capabilities, such as configuration, dependency injection (DI), and logging.

自 ASP.NET Core 3.0 起,建议为 HTTP 和非 HTTP 工作负载使用泛型主机。Starting in ASP.NET Core 3.0, Generic Host is recommended for both HTTP and non-HTTP workloads. HTTP 服务器实现(如果包括)作为 IHostedService 的实现运行。An HTTP server implementation, if included, runs as an implementation of IHostedService. IHostedService 是可用于其他工作负载的接口。IHostedService is an interface that can be used for other workloads as well.

对于 Web 应用,不再建议使用 Web 主机,但该主机仍可用于后向兼容性。Web Host is no longer recommended for web apps but remains available for backward compatibility.

备注

本文的其余部分尚未针对 3.0 进行更新。This remainder of this article hasn't been updated for 3.0.

ASP.NET Core 应用配置和启动主机。ASP.NET Core apps configure and launch a host. 主机负责应用程序启动和生存期管理。The host is responsible for app startup and lifetime management.

本文介绍 ASP.NET Core 泛型主机 (HostBuilder),该主机用于无法处理 HTTP 请求的应用。This article covers the ASP.NET Core Generic Host (HostBuilder), which is used for apps that don't process HTTP requests.

泛型主机的用途是将 HTTP 管道从 Web 主机 API 中分离出来,从而启用更多的主机方案。The purpose of Generic Host is to decouple the HTTP pipeline from the Web Host API to enable a wider array of host scenarios. 基于泛型主机的消息、后台任务和其他非 HTTP 工作负载可从横切功能(如配置、依赖关系注入 [DI] 和日志记录)中受益。Messaging, background tasks, and other non-HTTP workloads based on Generic Host benefit from cross-cutting capabilities, such as configuration, dependency injection (DI), and logging.

泛型主机是 ASP.NET Core 2.1 中的新增功能,不适用于 Web 承载方案。Generic Host is new in ASP.NET Core 2.1 and isn't suitable for web hosting scenarios. 对于 Web 承载方案,请使用 Web 主机For web hosting scenarios, use the Web Host. 泛型主机将在未来版本中替换 Web 主机,并在 HTTP 和非 HTTP 方案中充当主要的主机 API。Generic Host will replace Web Host in a future release and act as the primary host API in both HTTP and non-HTTP scenarios.

查看或下载示例代码如何下载View or download sample code (how to download)

Visual Studio Code 中运行示例应用时,请使用外部或集成终端。When running the sample app in Visual Studio Code, use an external or integrated terminal. 请勿在 internalConsole 中运行示例。Don't run the sample in an internalConsole.

在 Visual Studio Code 中设置控制台:To set the console in Visual Studio Code:

  1. 打开 .vscode/launch.json 文件。Open the .vscode/launch.json file.
  2. 在 .NET Core 启动(控制台)配置中,找到控制台条目。In the .NET Core Launch (console) configuration, locate the console entry. 将值设置为 externalTerminalintegratedTerminalSet the value to either externalTerminal or integratedTerminal.

介绍Introduction

通用主机库位于 Microsoft.Extensions.Hosting 命名空间中,由 Microsoft.Extensions.Hosting 包提供。The Generic Host library is available in the Microsoft.Extensions.Hosting namespace and provided by the Microsoft.Extensions.Hosting package. Microsoft.AspNetCore.App 元包(ASP.NET Core 2.1 或更高版本)中包括 Microsoft.Extensions.Hosting 包。The Microsoft.Extensions.Hosting package is included in the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later).

IHostedService 是执行代码的入口点。IHostedService is the entry point to code execution. 每个 IHostedService 实现都按照 ConfigureServices 中服务注册的顺序执行。Each IHostedService implementation is executed in the order of service registration in ConfigureServices. 主机启动时,每个 IHostedService 上都会调用 StartAsync,主机正常关闭时,以反向注册顺序调用 StopAsyncStartAsync is called on each IHostedService when the host starts, and StopAsync is called in reverse registration order when the host shuts down gracefully.

设置主机Set up a host

IHostBuilder 是供库和应用初始化、生成和运行主机的主要组件:IHostBuilder is the main component that libraries and apps use to initialize, build, and run the host:

public static async Task Main(string[] args)
{
    var host = new HostBuilder()
        .Build();

    await host.RunAsync();
}

选项Options

HostOptions 配置 IHost 的选项。HostOptions configure options for the IHost.

关闭超时值Shutdown timeout

ShutdownTimeout 设置 StopAsync 的超时值。ShutdownTimeout sets the timeout for StopAsync. 默认值为 5 秒。The default value is five seconds.

Program.Main 中的以下选项配置将默认值为 5 秒的关闭超时值增加至 20 秒:The following option configuration in Program.Main increases the default five second shutdown timeout to 20 seconds:

var host = new HostBuilder()
    .ConfigureServices((hostContext, services) =>
    {
        services.Configure<HostOptions>(option =>
        {
            option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
        });
    })
    .Build();

默认服务Default services

在主机初始化期间注册以下服务:The following services are registered during host initialization:

主机配置Host configuration

主机配置的创建方式如下:Host configuration is created by:

扩展方法Extension methods

应用程序键(名称)Application key (name)

IHostingEnvironment.ApplicationName 属性是在主机构造期间通过主机配置设定的。The IHostingEnvironment.ApplicationName property is set from host configuration during host construction. 要显式设置值,请使用 HostDefaults.ApplicationKeyTo set the value explicitly, use the HostDefaults.ApplicationKey:

密钥:applicationNameKey: applicationName
类型:stringType: string
默认值:包含应用入口点的程序集的名称。Default: The name of the assembly containing the app's entry point.
设置使用HostBuilderContext.HostingEnvironment.ApplicationNameSet using: HostBuilderContext.HostingEnvironment.ApplicationName
环境变量<PREFIX_>APPLICATIONNAME<PREFIX_>用户定义的可选前缀Environment variable: <PREFIX_>APPLICATIONNAME (<PREFIX_> is optional and user-defined)

内容根Content root

此设置确定主机从哪里开始搜索内容文件。This setting determines where the host begins searching for content files.

:contentRootKey: contentRoot
类型:stringType: string
默认值:默认为应用程序集所在的文件夹。Default: Defaults to the folder where the app assembly resides.
设置使用UseContentRootSet using: UseContentRoot
环境变量<PREFIX_>CONTENTROOT<PREFIX_>用户定义的可选前缀Environment variable: <PREFIX_>CONTENTROOT (<PREFIX_> is optional and user-defined)

如果路径不存在,主机将无法启动。If the path doesn't exist, the host fails to start.

var host = new HostBuilder()
    .UseContentRoot("c:\\<content-root>")

环境Environment

设置应用的环境Sets the app's environment.

:环境Key: environment
类型:stringType: string
默认值:生产Default: Production
设置使用UseEnvironmentSet using: UseEnvironment
环境变量<PREFIX_>ENVIRONMENT<PREFIX_>用户定义的可选前缀Environment variable: <PREFIX_>ENVIRONMENT (<PREFIX_> is optional and user-defined)

环境可以设置为任何值。The environment can be set to any value. 框架定义的值包括 Development``StagingProductionFramework-defined values include Development, Staging, and Production. 值不区分大小写。Values aren't case sensitive.

var host = new HostBuilder()
    .UseEnvironment(EnvironmentName.Development)

ConfigureHostConfigurationConfigureHostConfiguration

ConfigureHostConfiguration 使用 IConfigurationBuilder 来为主机创建 IConfigurationConfigureHostConfiguration uses an IConfigurationBuilder to create an IConfiguration for the host. 主机配置用于初始化 IHostingEnvironment,以供在应用的构建过程中使用。The host configuration is used to initialize the IHostingEnvironment for use in the app's build process.

可多次调用 ConfigureHostConfiguration,并得到累计结果。ConfigureHostConfiguration can be called multiple times with additive results. 主机使用上一次在一个给定键上设置值的选项。The host uses whichever option sets a value last on a given key.

主机配置自动流向应用配置(ConfigureAppConfiguration 和应用的其余部分)。Host configuration automatically flows to app configuration (ConfigureAppConfiguration and the rest of the app).

默认情况下不包括提供程序。No providers are included by default. 必须在 ConfigureHostConfiguration 中显式指定应用所需的任何配置提供程序,包括:You must explicitly specify whatever configuration providers the app requires in ConfigureHostConfiguration, including:

  • 文件配置(例如,来自 hostsettings.json 文件)。File configuration (for example, from a hostsettings.json file).
  • 环境变量配置。Environment variable configuration.
  • 命令行参数配置。Command-line argument configuration.
  • 任何其他所需的配置提供程序。Any other required configuration providers.

通过使用 SetBasePath 指定应用的基本路径,然后调用其中一个文件配置提供程序,可以启用主机的文件配置。File configuration of the host is enabled by specifying the app's base path with SetBasePath followed by a call to one of the file configuration providers. 示例应用使用 JSON 文件 hostsettings.json,并调用 AddJsonFile 来使用文件的主机配置设置。The sample app uses a JSON file, hostsettings.json, and calls AddJsonFile to consume the file's host configuration settings.

要添加主机的环境变量配置,请在主机生成器上调用 AddEnvironmentVariablesTo add environment variable configuration of the host, call AddEnvironmentVariables on the host builder. AddEnvironmentVariables 接受用户定义的前缀(可选)。AddEnvironmentVariables accepts an optional user-defined prefix. 示例应用使用前缀 PREFIX_The sample app uses a prefix of PREFIX_. 当系统读取环境变量时,便会删除前缀。The prefix is removed when the environment variables are read. 配置示例应用的主机后,PREFIX_ENVIRONMENT 的环境变量值就变成 environment 密钥的主机配置值。When the sample app's host is configured, the environment variable value for PREFIX_ENVIRONMENT becomes the host configuration value for the environment key.

在开发过程中,如果使用 Visual Studio 或通过 dotnet run 运行应用,可能会在 Properties/launchSettings.json 文件中设置环境变量。During development when using Visual Studio or running an app with dotnet run, environment variables may be set in the Properties/launchSettings.json file. 若在开发过程中使用 Visual Studio Code,可能会在 .vscode/launch.json 文件中设置环境变量。In Visual Studio Code, environment variables may be set in the .vscode/launch.json file during development. 有关更多信息,请参见在 ASP.NET Core 中使用多个环境For more information, see 在 ASP.NET Core 中使用多个环境.

通过调用 AddCommandLine 可添加命令行配置Command-line configuration is added by calling AddCommandLine. 最后添加命令行配置以允许命令行参数替代之前配置提供程序提供的配置。Command-line configuration is added last to permit command-line arguments to override configuration provided by the earlier configuration providers.

hostsettings.json:hostsettings.json:

{
  "environment": "Development"
}

可以通过 applicationNamecontentRoot 键提供其他配置。Additional configuration can be provided with the applicationName and contentRoot keys.

示例 HostBuilder 配置使用 ConfigureHostConfigurationExample HostBuilder configuration using ConfigureHostConfiguration:

var host = new HostBuilder()
    .ConfigureHostConfiguration(configHost =>
    {
        configHost.SetBasePath(Directory.GetCurrentDirectory());
        configHost.AddJsonFile("hostsettings.json", optional: true);
        configHost.AddEnvironmentVariables(prefix: "PREFIX_");
        configHost.AddCommandLine(args);
    })

ConfigureAppConfigurationConfigureAppConfiguration

通过在 IHostBuilder 实现上调用 ConfigureAppConfiguration 创建应用配置。App configuration is created by calling ConfigureAppConfiguration on the IHostBuilder implementation. ConfigureAppConfiguration 使用 IConfigurationBuilder 来为应用创建 IConfigurationConfigureAppConfiguration uses an IConfigurationBuilder to create an IConfiguration for the app. 可多次调用 ConfigureAppConfiguration,并得到累计结果。ConfigureAppConfiguration can be called multiple times with additive results. 应用使用上一次在一个给定键上设置值的选项。The app uses whichever option sets a value last on a given key. HostBuilderContext.Configuration 中提供 ConfigureAppConfiguration 创建的配置,以供进行后续操作和在 Services 中使用。The configuration created by ConfigureAppConfiguration is available at HostBuilderContext.Configuration for subsequent operations and in Services.

应用配置会自动接收 ConfigureHostConfiguration 提供的主机配置。App configuration automatically receives host configuration provided by ConfigureHostConfiguration.

示例应用配置使用 ConfigureAppConfigurationExample app configuration using ConfigureAppConfiguration:

var host = new HostBuilder()
    .ConfigureAppConfiguration((hostContext, configApp) =>
    {
        configApp.SetBasePath(Directory.GetCurrentDirectory());
        configApp.AddJsonFile("appsettings.json", optional: true);
        configApp.AddJsonFile(
            $"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", 
            optional: true);
        configApp.AddEnvironmentVariables(prefix: "PREFIX_");
        configApp.AddCommandLine(args);
    })

appsettings.json:appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

appsettings.Development.json:appsettings.Development.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

appsettings.Production.json:appsettings.Production.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Error",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

要将设置文件移动到输出目录,请在项目文件中将设置文件指定为 MSBuild 项目项To move settings files to the output directory, specify the settings files as MSBuild project items in the project file. 示例应用移动具有以下 <Content> 项的 JSON 应用设置文件和 hostsettings.json:The sample app moves its JSON app settings files and hostsettings.json with the following <Content> item:

<ItemGroup>
  <Content Include="**\*.json" Exclude="bin\**\*;obj\**\*" 
      CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

ConfigureServicesConfigureServices

ConfigureServices 将服务添加到应用的依赖关系注入容器。ConfigureServices adds services to the app's dependency injection container. 可多次调用 ConfigureServices,并得到累计结果。ConfigureServices can be called multiple times with additive results.

托管服务是一个类,具有实现 IHostedService 接口的后台任务逻辑。A hosted service is a class with background task logic that implements the IHostedService interface. 有关更多信息,请参见在 ASP.NET Core 中使用托管服务实现后台任务For more information, see 在 ASP.NET Core 中使用托管服务实现后台任务.

示例应用使用 AddHostedService 扩展方法向应用添加生存期事件 LifetimeEventsHostedService 和定时后台任务 TimedHostedService 服务:The sample app uses the AddHostedService extension method to add a service for lifetime events, LifetimeEventsHostedService, and a timed background task, TimedHostedService, to the app:

var host = new HostBuilder()
    .ConfigureServices((hostContext, services) =>
    {
        if (hostContext.HostingEnvironment.IsDevelopment())
        {
            // Development service configuration
        }
        else
        {
            // Non-development service configuration
        }

        services.AddHostedService<LifetimeEventsHostedService>();
        services.AddHostedService<TimedHostedService>();
    })

ConfigureLoggingConfigureLogging

ConfigureLogging 添加了一个委托来配置提供的 ILoggingBuilderConfigureLogging adds a delegate for configuring the provided ILoggingBuilder. 可以利用相加结果多次调用 ConfigureLoggingConfigureLogging may be called multiple times with additive results.

var host = new HostBuilder()
    .ConfigureLogging((hostContext, configLogging) =>
    {
        configLogging.AddConsole();
        configLogging.AddDebug();
    })

UseConsoleLifetimeUseConsoleLifetime

UseConsoleLifetime 侦听 Ctrl+C/SIGINT 或 SIGTERM 并调用 StopApplication 来启动关闭进程。UseConsoleLifetime listens for Ctrl+C/SIGINT or SIGTERM and calls StopApplication to start the shutdown process. UseConsoleLifetime 解除阻止 RunAsyncWaitForShutdownAsync 等扩展。UseConsoleLifetime unblocks extensions such as RunAsync and WaitForShutdownAsync. ConsoleLifetime 预注册为默认生存期实现。ConsoleLifetime is pre-registered as the default lifetime implementation. 使用注册的最后一个生存期。The last lifetime registered is used.

var host = new HostBuilder()
    .UseConsoleLifetime()

容器配置Container configuration

为支持插入其他容器中,主机可以接受 IServiceProviderFactory<TContainerBuilder>To support plugging in other containers, the host can accept an IServiceProviderFactory<TContainerBuilder>. 提供工厂不属于 DI 容器注册,而是用于创建具体 DI 容器的主机内部函数。Providing a factory isn't part of the DI container registration but is instead a host intrinsic used to create the concrete DI container. UseServiceProviderFactory(IServiceProviderFactory<TContainerBuilder>) 重写用于创建应用的服务提供程序的默认工厂。UseServiceProviderFactory(IServiceProviderFactory<TContainerBuilder>) overrides the default factory used to create the app's service provider.

ConfigureContainer 方法托管自定义容器配置。Custom container configuration is managed by the ConfigureContainer method. ConfigureContainer 提供在基础主机 API 的基础之上配置容器的强类型体验。ConfigureContainer provides a strongly-typed experience for configuring the container on top of the underlying host API. 可以利用相加结果多次调用 ConfigureContainerConfigureContainer can be called multiple times with additive results.

为应用创建服务容器:Create a service container for the app:

namespace GenericHostSample
{
    internal class ServiceContainer
    {
    }
}

提供服务容器工厂:Provide a service container factory:

using System;
using Microsoft.Extensions.DependencyInjection;

namespace GenericHostSample
{
    internal class ServiceContainerFactory : 
        IServiceProviderFactory<ServiceContainer>
    {
        public ServiceContainer CreateBuilder(
            IServiceCollection services)
        {
            return new ServiceContainer();
        }

        public IServiceProvider CreateServiceProvider(
            ServiceContainer containerBuilder)
        {
            throw new NotImplementedException();
        }
    }
}

使用该工厂并为应用配置自定义服务容器:Use the factory and configure the custom service container for the app:

var host = new HostBuilder()
    .UseServiceProviderFactory<ServiceContainer>(new ServiceContainerFactory())
    .ConfigureContainer<ServiceContainer>((hostContext, container) =>
    {
    })

扩展性Extensibility

IHostBuilder 上使用扩展方法实现主机扩展性。Host extensibility is performed with extension methods on IHostBuilder. 以下示例介绍扩展方法如何使用 在 ASP.NET Core 中使用托管服务实现后台任务 中所示的 TimedHostedService 示例来扩展 IHostBuilder 实现。The following example shows how an extension method extends an IHostBuilder implementation with the TimedHostedService example demonstrated in 在 ASP.NET Core 中使用托管服务实现后台任务.

var host = new HostBuilder()
    .UseHostedService<TimedHostedService>()
    .Build();

await host.StartAsync();

应用建立 UseHostedService 扩展方法,以注册在 T 中传递的托管服务:An app establishes the UseHostedService extension method to register the hosted service passed in T:

using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public static class Extensions
{
    public static IHostBuilder UseHostedService<T>(this IHostBuilder hostBuilder)
        where T : class, IHostedService, IDisposable
    {
        return hostBuilder.ConfigureServices(services =>
            services.AddHostedService<T>());
    }
}

管理主机Manage the host

IHost 实现负责启动和停止服务容器中注册的 IHostedService 实现。The IHost implementation is responsible for starting and stopping the IHostedService implementations that are registered in the service container.

运行Run

Run 运行应用并阻止调用线程,直到关闭主机:Run runs the app and blocks the calling thread until the host is shut down:

public class Program
{
    public void Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        host.Run();
    }
}

RunAsyncRunAsync

RunAsync 运行应用并返回在触发取消令牌或关闭时完成的 TaskRunAsync runs the app and returns a Task that completes when the cancellation token or shutdown is triggered:

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        await host.RunAsync();
    }
}

RunConsoleAsyncRunConsoleAsync

RunConsoleAsync 启用控制台支持、生成和启动主机,以及等待 Ctrl+C/SIGINT 或 SIGTERM 关闭。RunConsoleAsync enables console support, builds and starts the host, and waits for Ctrl+C/SIGINT or SIGTERM to shut down.

public class Program
{
    public static async Task Main(string[] args)
    {
        var hostBuilder = new HostBuilder();

        await hostBuilder.RunConsoleAsync();
    }
}

Start 和 StopAsyncStart and StopAsync

Start 同步启动主机。Start starts the host synchronously.

StopAsync 尝试在提供的超时时间内停止主机。StopAsync attempts to stop the host within the provided timeout.

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            host.Start();

            await host.StopAsync(TimeSpan.FromSeconds(5));
        }
    }
}

StartAsync 和 StopAsyncStartAsync and StopAsync

StartAsync 启动应用。StartAsync starts the app.

StopAsync 停止应用。StopAsync stops the app.

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            await host.StartAsync();

            await host.StopAsync();
        }
    }
}

WaitForShutdownWaitForShutdown

WaitForShutdown 通过 IHostLifetime 触发,例如 ConsoleLifetime(侦听 Ctrl+C/SIGINT 或 SIGTERM)。WaitForShutdown is triggered via the IHostLifetime, such as ConsoleLifetime (listens for Ctrl+C/SIGINT or SIGTERM). WaitForShutdown 调用 StopAsyncWaitForShutdown calls StopAsync.

public class Program
{
    public void Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            host.Start();

            host.WaitForShutdown();
        }
    }
}

WaitForShutdownAsyncWaitForShutdownAsync

WaitForShutdownAsync 返回在通过给定的令牌和调用 StopAsync 来触发关闭时完成的 TaskWaitForShutdownAsync returns a Task that completes when shutdown is triggered via the given token and calls StopAsync.

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            await host.StartAsync();

            await host.WaitForShutdownAsync();
        }

    }
}

外部控件External control

使用可从外部调用的方法,能够实现主机的外部控件:External control of the host can be achieved using methods that can be called externally:

public class Program
{
    private IHost _host;

    public Program()
    {
        _host = new HostBuilder()
            .Build();
    }

    public async Task StartAsync()
    {
        _host.StartAsync();
    }

    public async Task StopAsync()
    {
        using (_host)
        {
            await _host.StopAsync(TimeSpan.FromSeconds(5));
        }
    }
}

StartAsync 开始时调用 WaitForStartAsync,在继续之前,会一直等待该操作完成。WaitForStartAsync is called at the start of StartAsync, which waits until it's complete before continuing. 它可用于延迟启动,直到外部事件发出信号。This can be used to delay startup until signaled by an external event.

IHostingEnvironment 接口IHostingEnvironment interface

IHostingEnvironment 提供有关应用托管环境的信息。IHostingEnvironment provides information about the app's hosting environment. 使用构造函数注入获取 IHostingEnvironment 以使用其属性和扩展方法:Use constructor injection to obtain the IHostingEnvironment in order to use its properties and extension methods:

public class MyClass
{
    private readonly IHostingEnvironment _env;

    public MyClass(IHostingEnvironment env)
    {
        _env = env;
    }

    public void DoSomething()
    {
        var environmentName = _env.EnvironmentName;
    }
}

有关更多信息,请参见在 ASP.NET Core 中使用多个环境For more information, see 在 ASP.NET Core 中使用多个环境.

IApplicationLifetime 接口IApplicationLifetime interface

IApplicationLifetime 允许启动后和关闭活动,包括正常关闭请求。IApplicationLifetime allows for post-startup and shutdown activities, including graceful shutdown requests. 接口上的三个属性是用于注册 Action 方法(用于定义启动和关闭事件)的取消标记。Three properties on the interface are cancellation tokens used to register Action methods that define startup and shutdown events.

取消标记Cancellation Token 触发条件Triggered when…
ApplicationStarted 主机已完全启动。The host has fully started.
ApplicationStopped 主机正在完成正常关闭。The host is completing a graceful shutdown. 应处理所有请求。All requests should be processed. 关闭受到阻止,直到完成此事件。Shutdown blocks until this event completes.
ApplicationStopping 主机正在执行正常关闭。The host is performing a graceful shutdown. 仍在处理请求。Requests may still be processing. 关闭受到阻止,直到完成此事件。Shutdown blocks until this event completes.

构造函数将 IApplicationLifetime 服务注入到任何类中。Constructor-inject the IApplicationLifetime service into any class. 示例应用将构造函数注入到 LifetimeEventsHostedService 类(一个 IHostedService 实现)中,用于注册事件。The sample app uses constructor injection into a LifetimeEventsHostedService class (an IHostedService implementation) to register the events.

LifetimeEventsHostedService.cs:LifetimeEventsHostedService.cs:

internal class LifetimeEventsHostedService : IHostedService
{
    private readonly ILogger _logger;
    private readonly IApplicationLifetime _appLifetime;

    public LifetimeEventsHostedService(
        ILogger<LifetimeEventsHostedService> logger, 
        IApplicationLifetime appLifetime)
    {
        _logger = logger;
        _appLifetime = appLifetime;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _appLifetime.ApplicationStarted.Register(OnStarted);
        _appLifetime.ApplicationStopping.Register(OnStopping);
        _appLifetime.ApplicationStopped.Register(OnStopped);

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    private void OnStarted()
    {
        _logger.LogInformation("OnStarted has been called.");

        // Perform post-startup activities here
    }

    private void OnStopping()
    {
        _logger.LogInformation("OnStopping has been called.");

        // Perform on-stopping activities here
    }

    private void OnStopped()
    {
        _logger.LogInformation("OnStopped has been called.");

        // Perform post-stopped activities here
    }
}

StopApplication 请求终止应用。StopApplication requests termination of the app. 以下类在调用类的 Shutdown 方法时使用 StopApplication 正常关闭应用:The following class uses StopApplication to gracefully shut down an app when the class's Shutdown method is called:

public class MyClass
{
    private readonly IApplicationLifetime _appLifetime;

    public MyClass(IApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public void Shutdown()
    {
        _appLifetime.StopApplication();
    }
}

其他资源Additional resources