#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
обрабатывает токен отмены для меня. Отлично!