本文介绍了配置 .NET Core 通用主机时如何应用 HostOptions.ShutdownTimeout?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 .NET Core 通用主机(而不是 Web 主机)来构建需要相当长的优雅关闭时间的控制台应用程序.来自

I am using the .NET Core Generic Host (not Web Host) to build a Console app that needs a rather lengthy graceful shutdown. From the source code in

aspnet/Hosting/src/Microsoft.Extensions.Hosting/HostOptions

很明显,ShutdownTimeout 选项可用于更改作为参数提供给 ShutdownAsync 的取消令牌中的关闭超时.默认为 5 秒.

it seems pretty clear that the ShutdownTimeout option can be used to change the shutdown timeout in the cancellation token that is provided as a parameter to ShutdownAsync. By default it is 5 seconds.

但是,我不知道在哪里以及如何编写代码以在 HostBuilder 配置代码中指定此选项,您通常将其放入 Program.cs文件.

However, I can't figure out where and how to write the code to specify this option in the HostBuilder configuration code that you typically put in the Program.cs file.

有人可以发布一些代码来展示如何做到这一点吗?

Can someone post some code that shows how to do this?

推荐答案

好吧,我终于想通了……这里是我的 Program.cs Main 函数中的配置代码的大纲,省略了大部分项目,以显示HostOptins.ShutdownTimeout 的配置在哪里.

OK, I finally figured it out ... Here's an outline the configuration code in my Program.cs Main function, with most of the items elided, to show where the configuration for HostOptins.ShutdownTimeout goes.

public static async Task Main(string[] args)
{
    var host = new HostBuilder()
        .ConfigureHostConfiguration(configHost => {...})
        .ConfigureAppConfiguration((hostContext, configApp) => {...})
        .ConfigureServices((hostContext, services) =>
        {
           services.AddHostedService<ApplicationLifetime>();          
           ...
           services.Configure<HostOptions>(
                opts => opts.ShutdownTimeout = TimeSpan.FromSeconds(10));
        })
        .ConfigureLogging(...)
        .UseConsoleLifetime()
        .Build();

    try
    {
        await host.RunAsync();
    }
    catch(OperationCanceledException)
    {
        ; // suppress
    }
}

为了使这个工作,这里是我的 IHostedService 类中的 StopAsync 方法:

To make the this work, here is the StopAsync method in my IHostedService class:

public async Task StopAsync(CancellationToken cancellationToken)
{
    try
    {
        await Task.Delay(Timeout.Infinite, cancellationToken);
    }
    catch(TaskCanceledException)
    {
        _logger.LogDebug("TaskCanceledException in StopAsync");
        // do not rethrow
    }
}

参见 在 .NET 中使用通用主机正常关闭核心 2.1 了解更多详情.

See Graceful shutdown with Generic Host in .NET Core 2.1 for more details about this.

顺便说一句,Program.Main 中的 catch 块对于避免未处理的异常是必要的,即使我正在捕获通过等待 StopAsync 中的取消标记生成的异常;因为框架内部版本的 StopAsync 似乎也在关闭超时到期时生成了未处理的 OperationCanceledException.

Btw, the catch block in Program.Main is necessary to avoid an unhandled exception, even though I am catching the exception generated by awaiting the cancellation token in StopAsync; because it seems that an unhandled OperationCanceledException is also generated at expiration of the shutdown timeout by the framework-internal version of StopAsync.

这篇关于配置 .NET Core 通用主机时如何应用 HostOptions.ShutdownTimeout?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 07:44