Класс WebApplication. Запуск и остановка приложения, доступ к событиям жизненного цикла приложения

Класс WebApplication реализует сразу три интерфейса IHost, IApplicationBuilder и IEndpointRouteBuilder и используется для широкого круга задач — от запуска и остановки приложения, до настройки маршрутов, с которыми сопоставляются запросы пользователей, конвейера обработки запросов и получения доступа к настройкам приложения.

Свойства и методы класса WebApplication

Объект этого класса создается при вызове метода Build() класса WebApplicationBuilder

var builder = WebApplication.CreateBuilder(args);

//настройка приложения

var app = builder.Build(); //создаем объект типа WebApplication

// получение доступа к настройкам приложения

Класс WebApplication предоставляет свойства, представленные в таблице:

Свойство Значение свойства Описание
Configuration IConfiguration представляет конфигурацию приложения в виде объекта IConfiguration
Environment IWebHostEnvironment представляет данные об окружении приложения в виде IWebHostEnvironment
Lifetime IHostApplicationLifetime позволяет пользователям получать уведомления о событиях жизненного цикла приложения
Logger ILogger представляет объект для ведения журнала для приложения
Services IServiceProvider представляет список сервисов приложения
Urls ICollection<String> представляет список URL-адресов, к которым привязан HTTP-сервер.

Кроме того, класс WebApplication содержит методы для управления приложением

Метод Описание
Run(String) Запускает приложение и блокирует вызывающий поток, пока работа узла не будет завершена. В параметре метода можно указать url по которому будет доступно приложение.
RunAsync(String) Запускает приложение и возвращает объект Task, который завершается только при активации токена или завершении работы
StartAsync(CancellationToken) Запускает приложение
StopAsync(CancellationToken) Завершает работу приложения

Запуск и остановка приложения

Чтобы понять суть работы методов у WebApplication, создадим новый проект ASP.NET Core Web API и добавим в самый конец файла строку:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddOpenApi();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();
//новая строка кода
app.Logger.LogInformation("Приложение запущено");

Здесь мы пытаемся вывести в лог строку «Приложение запущено» после того, как выполняется метод Run(). Забегая немного вперед, отмечу, что по умолчанию приложение настраивается на ведение лога в том числе в консоли. Если вы запустите приложение, то увидите, что в консоль ничего не будет выведено так как метод Run() блокирует вызывающий поток. То же самое произойдет и при попытке запуска приложения с использованием метода RunAsync().

Если мы хотим произвести какие-либо действия уже после того, как приложение запущено, нам необходимо использовать метод StartAsync(). Перепишем код приложение следующим образом

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddOpenApi();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

await app.StartAsync();
app.Logger.LogInformation("Приложение запущено");
await app.WaitForShutdownAsync();

Теперь мы используем для запуска приложения метод StartAsync(), который не будет блокировать вызывающий поток, а сразу после запуска вернет результат.

Для того, чтобы приложение не завершило работу после вывода сообщения в консоль мы также добавили в конце вызов метода WaitForShutdownAsync(), который вернет нам результат только после того, как приложение завершит свою работу. Теперь можно запустить приложение и убедиться, что строка с сообщением выведена в консоль

Также стоит отметить, что, если вам по каким-то причинам, потребуется вручную остановить работу приложения, то можно использоваться связку методов: StartAsync() – для запуска и StopAsync() – для остановки приложения.

Доступ к событиям жизненного цикла приложения

Иногда может потребоваться волнение каких-либо действий в момент запуска приложения или, наоборот, в момент, когда приложение начинает свою остановку. Для этого мы можем получить доступ к событиям жизненного цикла приложения. Свойство Lifetime класса WebApplication реализует интерфейс IHostApplicationLifetime у которого определены следующие свойства

Свойство Тип Описание
ApplicationStarted CancellationToken Срабатывает при полной загрузке узла приложения
ApplicationStopped CancellationToken Срабатывает, когда узел приложения выполнил корректное завершение работы
ApplicationStopping CancellationToken Срабатывает, когда хост приложения выполняет корректное завершение работы. Завершение работы будет блокироваться до завершения этого события

Таким образом, используя эти свойства, мы можем отслеживать жизненный цикла нашего приложения – когда оно полностью запущено, начало корректное завершение работы и когда приложение полностью завершает свою работу. Продемонстрировать работу с этими свойствами можно на следующем примере:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Lifetime.ApplicationStarted.Register(() => InvokeEvent(app.Logger,"Приложение запущено"));
app.Lifetime.ApplicationStopping.Register(() => InvokeEvent(app.Logger, "Приложение начало корректную остановку"));
app.Lifetime.ApplicationStopped.Register(() => InvokeEvent(app.Logger, "Приложение полностью остановлено"));

app.Run();


void InvokeEvent(ILogger logger, string text)
{
    logger.LogInformation($"{DateTime.Now} {text}");
}

Прежде всего, мы регистрируем функцию обратного вызова, код которой будет выполняться при срабатывании свойств объекта Lifetime: OnStarted(), OnStopping() и OnStopped():

app.Lifetime.ApplicationStarted.Register(() => InvokeEvent(app.Logger,"Приложение запущено"));
app.Lifetime.ApplicationStopping.Register(() => InvokeEvent(app.Logger, "Приложение начало корректную остановку"));
app.Lifetime.ApplicationStopped.Register(() => InvokeEvent(app.Logger, "Приложение полностью остановлено"));

Сама функция обратного вызова достаточно простая

void InvokeEvent(ILogger logger, string text)
{
    logger.LogInformation($"{DateTime.Now} {text}");
}

Здесь мы запрашиваем в параметрах методов сервис для ведения логов – ILogger и выводим сообщение в лог об очередном событии жизненного цикла

Теперь запустим приложение в режиме отладки. В консоли мы должны увидеть первое сообщение об успешном запуске

Теперь, находясь в консоли приложения, нажмем сочетание клавиш Ctrl+C, что приведет к остановке приложения и мы увидим сообщения о ходе процесса остановки приложения

Как нетрудно догадаться, вместо простого вывода строки в лог приложения, внутри методов обратного вызова мы могли бы производить какую-либо полезную работу – запустить или остановить внешние процессы, используемые приложением, сохранить результаты работы и так далее.

Итого

Класс WebApplication используется для широкого круга задач. В этой части мы рассмотрели различные варианты запуска приложения, а также работу со свойством Lifetime, используя которое, мы можем получить доступ к событиям жизненного цикла приложения.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии