У меня есть стандартный c построитель хоста по умолчанию, как показано ниже:
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 секунд принудительно завершается.
Мои вопросы:
- Как я могу обнаружить команду docker выключения?
- Как я могу зарегистрировать оба метода выключения (через консоль или docker) в зависимости от метода, которым я звоню (иногда я могу отлаживать непосредственно в Visual Studio в качестве консоли, тогда как в основном я бы использовал через docker, но было бы неплохо автоматически зарегистрировать оба сценария ios).
ИЗМЕНИТЬ И ОБНОВИТЬ
Я видел ответы, спасибо, упоминание ловушки на AppDomain.CurrentDomain.ProcessExit
.
Для моего рабочего BackgroundService
интерфейс таков, что он имеет функцию:
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
тот же код) в пределах docker, stoppingToken не установлен.
Обратите внимание, я не вижу, что у меня есть доступ к этому источнику токенов, чтобы выполнить отмену.
Если я Зарегистрируйтесь в AppDomain.CurrentDomain.ProcessExit
, как я могу использовать это для установки stoppingToken (в отличие от создания собственного источника токена остановки, поскольку, хотя это возможно, хотелось бы избежать, если это возможно).
docker стоп