首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用通用主机IHostBuilder检测停靠点的关闭信号

使用通用主机IHostBuilder检测停靠点的关闭信号
EN

Stack Overflow用户
提问于 2020-07-08 20:35:54
回答 1查看 686关注 0票数 7

我有一个默认的通用主机生成器,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
public static IHostBuilder CreateDefaultBuilder(string[] args)
{
    var builder = Host.CreateDefaultBuilder(args);

    builder
        .ConfigureLogging((hostingContext, logging) =>
        {
            logging.ClearProviders();
            logging.AddConsole();
            if (hostingContext.HostingEnvironment.IsDevelopment() == true)
                logging.AddDebug();
        })
        .ConfigureHostConfiguration(configurationBuilder =>
        {
            configurationBuilder.AddCommandLine(args);
        })
        .ConfigureAppConfiguration((hostingContext, configApp) =>
        {
            var env = hostingContext.HostingEnvironment;
            Console.WriteLine(env.EnvironmentName);
        })
        .UseConsoleLifetime();

    return builder;
}

public static async Task Main(string[] args)
{
     var host = CreateDefaultBuilder(args)
                        .ConfigureServices((hostContext, services) =>
                        {
                            services.Configure<HostOptions>(option =>
                            {
                                option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
                            });

                            services.AddLogging();

                            services.AddSimpleInjector(container, options =>
                            {
                                // Hooks hosted services into the Generic Host pipeline while resolving them through Simple Injector
                                options.AddHostedService<Worker>();

                                // Allows injection of ILogger & IStringLocalizer dependencies into application components
                                options.AddLogging();
                                // options.AddLocalization();
                            });
                        })
                        .Build()
                        .UseSimpleInjector(container);

     config.Build();
     await host.RunAsync();
}

我使用UseConsoleLifetime和docker运行应用程序,它运行,但我似乎不能优雅地关闭。

我通过docker stop命令在PowerShell中优雅地向我的应用程序发送停止信号。

然而,不像我的控制台应用程序,我按control+C,应用程序没有得到这个停止命令,在10秒后被强制杀死。

我的问题是:

  1. 如何检测停靠程序关机命令?
  2. 如何根据调用的方法(通过控制台或停靠器)注册这两种关闭方法(有时,我可以在Visual中直接调试作为控制台,而大多数情况下,我会通过停靠器使用,但这两种情况下都可以自动注册)。

编辑和更新

我见过回复,谢谢,提到陷阱在AppDomain.CurrentDomain.ProcessExit上。

对于我的工作人员BackgroundService,接口是这样的,它具有以下功能:

代码语言:javascript
代码运行次数:0
运行
复制
public class Worker : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
             logger.LogInformation("running at: {time} - stoppingToken {stoppingToken}", DateTimeOffset.Now, stoppingToken.IsCancellationRequested);
             await Task.Delay(1000, stoppingToken);
        }
    }
}

无论何时发送UseConsoleLifetime,都会使用ctrl+c设置stoppingToken。

当在坞内使用相同的代码(包括UseConsoleLifetime相同的代码)时,不会设置stoppingToken。

注意,为了执行取消,我无法看到我可以访问这个令牌源。

如果我注册到AppDomain.CurrentDomain.ProcessExit,我如何使用它来设置stoppingToken (与创建自己的停止令牌源相反,就像可以执行的那样,如果可能的话,希望避免)。

EN

回答 1

Stack Overflow用户

发布于 2020-07-08 20:42:07

docker stop向容器中的主进程发送SIGTERM信号。为了处理这个问题和优雅地关闭,您需要捕获这个信号并执行适当的终止代码。因此,This问题描述了如何附加响应此信号的事件处理程序。

请注意,如果不捕获此信号,停靠者将在超时后强制关闭容器(默认情况下为10秒)。

要处理这两个问题,您可以提取运行的任何清理代码,以便优雅地关闭一个函数,并从两个处理程序中调用它。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62803245

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档