Как отменить веб-хостинг при остановке процесса

#c# #.net #asynchronous #asp.net-web-api #cancellation-token

#c# #.net #асинхронный #asp.net-web-api #отмена-токен

Вопрос:

Я только что попробовал использовать async Task Main метод в шаблонном веб-API (dotnet 5). Вот мой код котельной:

 public class Program
{
    public static async Task Main(string[] args)
    {
        await CreateHostBuilder(args).Build().RunAsync();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}
  

Я заметил, что RunAsync принимает токен отмены, и я бы хотел, чтобы это основывалось на закрытии приложения.

Мой вопрос — каков правильный (стандартный) способ настройки токена отмены здесь, который связан с завершением процесса?

Я мог бы сделать что-то вроде этого:

 public static async Task Main(string[] args)
{
    var cts = new CancellationTokenSource();

    AppDomain.CurrentDomain.UnhandledException  = (s, e) => { if (e.IsTerminating) cts.Cancel(); };
    AppDomain.CurrentDomain.ProcessExit  = (s, e) => cts.Cancel();
    Console.CancelKeyPress  = (s, e) => { e.Cancel = true; cts.Cancel(); };

    await CreateHostBuilder(args).Build().RunAsync(cts.Token);
}
  

Но интересно, есть ли более стандартный подход, который мне не хватает.

Заранее спасибо за любые советы!

Ответ №1:

Дизайн хоста .NET включает логику завершения работы приложения на основе внешних событий (например, CTRL C в консольном приложении) в реализацию интерфейса IHostLifetime.

Существующие реализации IHostLifetime включают консоль, службу Windows и systemd. Это в основном то, что UseWindowsService и UseSystemd регистр расширений, см., Например, Источник WindowServiceLifetimeHostBuilderExtensions. Реализации времени жизни обычно используют IHostApplicationLifetime для завершения работы приложения. Настройка веб-хостинга по умолчанию включает время жизни консоли.

Используя этот подход, одно приложение может быть настроено как консольное приложение, служба Windows или использовать любые другие требуемые триггеры завершения работы.

В противном случае не должно быть необходимости регистрировать прослушиватель отмены для любых событий завершения работы во время выполнения, таких как UnhandledException или ProcessExit поскольку процесс приложения в любом случае прерывается. Концепция хостинга основана на асинхронности на основе задач, она не порождает никаких последующих процессов или аналогичных ресурсов, которые оставались бы в живых после выхода Main .

Для получения более подробной информации см. Страницы документации веб-хоста и общего хоста.

Ответ №2:

Я только что нашел это UseConsoleLifetime() , которое можно установить в конструкторе веб-хостинга:

 public class Program
{
    public static async Task Main(string[] args)
    {
        await CreateHostBuilder(args).Build().RunAsync();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) => 
        Host.CreateDefaultBuilder(args)
            .UseConsoleLifetime()
            .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}
  

Теперь Microsoft.Hosting.LifeTime обрабатывает токен отмены для меня. Отлично!