【问题标题】:How to apply HostOptions.ShutdownTimeout when configuring .NET Core Generic Host?配置 .NET Core 通用主机时如何应用 HostOptions.ShutdownTimeout?
【发布时间】:2019-03-25 16:23:04
【问题描述】:

我正在使用 .NET Core 通用主机(不是 Web 主机)来构建一个控制台应用程序,该应用程序需要相当长时间的正常关闭。从源代码中

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

似乎很清楚ShutdownTimeout 选项可用于更改作为参数提供给ShutdownAsync 的取消令牌中的关闭超时。默认为 5 秒。

但是,我不知道在您通常放在 Program.cs 文件中的 HostBuilder 配置代码中指定此选项的代码的位置和方式。

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

【问题讨论】:

  • 你在使用 ASP.NET Core 吗?如果是这样,请编辑您的问题并将asp.net-core 标签添加到它,以便用户更容易找到它。此外,如果是这种情况,也许您正在寻找 UseShutdownTimeout() 扩展方法,您可以在您的网络主机构建器对象中调用它来配置关闭时间的 TimeSpan。
  • 不,我使用的是通用主机。我更新了问题以使其更清楚。 HostOptions 类定义了一个属性public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(5);,但我不清楚如何在HostBuilder 配置中应用它。
  • 我应该进一步说明我使用的是 .NET Core 2.1.1。

标签: c# .net-core


【解决方案1】:

好的,我终于弄明白了......这是我的 Program.cs Main 函数中的配置代码的概要,大部分项目都被省略了,以显示 HostOptins.ShutdownTimeout 的配置在哪里。

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 方法:

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

请参阅Graceful shutdown with Generic Host in .NET Core 2.1 了解更多详情。

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

【讨论】:

  • 我可能错了,或者以前不可能,但为什么不直接使用services.Configure&lt;HostOptions&gt;(x =&gt; x.ShutdownTimeout = TimeSpan.FromSeconds(10))
【解决方案2】:

ASP.NET Core 6+ 的相关答案:

解决方案一:

var builder = WebApplication.CreateBuilder(args);
//...
builder.WebHost.UseShutdownTimeout(TimeSpan.FromSeconds(30));
//...
var app = builder.Build();

解决方案 2:

var builder = WebApplication.CreateBuilder(args);
//...
builder.Services.Configure<HostOptions>(
     opts => opts.ShutdownTimeout = TimeSpan.FromSeconds(30));
//...
var app = builder.Build();

解决方案 3:

var builder = WebApplication.CreateBuilder(args);
//...
builder.Services.PostConfigureAll<HostOptions>(opts => 
    opts.ShutdownTimeout = TimeSpan.FromSeconds(30));
//...
var app = builder.Build();

解决方案 3 将在所有其他解决方案之后应用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 2020-08-15
    • 2021-11-04
    • 1970-01-01
    • 2019-06-02
    • 2020-02-20
    • 2019-08-15
    相关资源
    最近更新 更多