TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
НеСерьезный шарпист

30 Dec 2024, 20:15

Открыть в Telegram Поделиться Пожаловаться

В .NET 8 были выпущены интересные изменения в библиотеке Microsoft.Extensions.Hosting, на которые многие почему-то не обратили внимания.

Данная либа предоставляет возможности для создания фоновых задач в шаблоне ASP.NET приложения, а также для создания отдельных Worker-сервисов без привязки к веб-серверу (что, например, хорошо подходит для создания микросервисов, работающих с очередью брокера сообщений).

Приложение может содержать одну или несколько таких задач, реализующих IHostedService и регистрирующихся в контейнере внедрения зависимостей. Microsoft предоставляет готовую реализацию интерфейса IHostedService в виде базового абстрактного класса BackgroundService, предоставляет общую менимальную логику методов StartAsync() и StopAsync(), которая достаточно большинству фоновых задач. Чтобы использовать BackgroundService, необходимо унаследоваться от данного класса и реализуют абстрактный метод ExecuteAsync() с логикой фоновой задачи.
public class WorkerServiceOne : BackgroundService
{
private readonly ILogger _logger;

public WorkerServiceOne(ILogger logger)
{
_logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker 1 running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}

Для запуска служб создаем объект хоста и запускаем его. Вместе с запуском хоста будут запущены и все зарегистрированные службы.
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService();
services.AddHostedService();
})
.Build();

host.Run();
Таким образом, каждая задача IHostedService, зарегистрированная в di-контейнере, запускается последовательно путем вызова метода StartAsync(). То есть для запуска следующий задачи выполняется ожидание завершения метод StartAsync() предыдущей задачи. Очевидно, что медленный запуск одной из служб тормозит развертывание всего приложения. А при остановке приложения выполняется такая же синхронная логика с StopAsync(). Однако для StopAsync() настраивается таймаут завершения и нужно учитывать время завершения каждого конкретного сервиса, а если завершение одной из служб будет занимать слишком много времени, весь процесс завершения приложения может завершаться аварийно.

Для решения этих проблем в .NET 8 была добавлена возможность "параллельного" запуска и завершения, регистрируемых служб. Для этого теперь существуют опции конфигурации ServicesStartConcurrently и ServicesStopConcurrently.
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.Configure(options =>
{
options.ServicesStartConcurrently = true;
options.ServicesStopConcurrently = true;
});
services.AddHostedService();
services.AddHostedService();
})
.Build();

host.Run();

Сейчас код реализации "параллельного" запуска служб хоста выглядит примерно следующим образом:
if (_options.ServicesStartConcurrently)
{
List tasks = new List();

foreach (IHostedService hostedService in _hostedServices)
{
tasks.Add(Task.Run(() => StartAndTryToExecuteAsync(hostedService, combinedCancellationToken), combinedCancellationToken));
}

Task groupedTasks = Task.WhenAll(tasks);
}

То есть задачи по-прежнему запускаются в том же порядке, в котором они регистрируются в di, но они не ожидаются на этом этапе. Задачи добавляются в список, и только после запуска каждой задачи WhenAll используется для ожидания завершения StartAsync для каждой службы. В этом режиме запуск займет столько же времени, сколько самый медленный вызов StartAsync, что позволяет приложению в целом запуститься быстрее. Аналогичная история и с StopAsync.

1.7k 0 29 2 21
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot