Ответ
Да, создавал различные типы сервисов для выполнения фоновых задач и длительных операций.
1. Фоновые сервисы в ASP.NET Core (BackgroundService): Идеально для задач внутри веб-приложения: отправка email, обработка очередей, кэширование.
public class TimedHostedService : BackgroundService
{
private readonly ILogger<TimedHostedService> _logger;
private readonly IServiceScopeFactory _scopeFactory;
public TimedHostedService(ILogger<TimedHostedService> logger, IServiceScopeFactory scopeFactory)
{
_logger = logger;
_scopeFactory = scopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service running.");
using PeriodicTimer timer = new(TimeSpan.FromSeconds(5));
try
{
while (await timer.WaitForNextTickAsync(stoppingToken))
{
await using (var scope = _scopeFactory.CreateAsyncScope())
{
var scopedProcessor = scope.ServiceProvider
.GetRequiredService<IScopedProcessingService>();
await scopedProcessor.DoWorkAsync(stoppingToken);
}
}
}
catch (OperationCanceledException)
{
_logger.LogInformation("Timed Hosted Service is stopping.");
}
}
}
// Регистрация в Program.cs: builder.Services.AddHostedService<TimedHostedService>();
2. Windows Services (ранее NT Services): Для автономных служб, работающих под управлением Windows Service Control Manager (SCM).
using System.ServiceProcess;
public class MyWindowsService : ServiceBase
{
private BackgroundWorker _worker;
protected override void OnStart(string[] args)
{
_worker = new BackgroundWorker();
_worker.DoWork += (s, e) => { /* Долгая фоновая работа */ };
_worker.RunWorkerAsync();
}
protected override void OnStop()
{
_worker?.CancelAsync();
// Освобождение ресурсов
}
}
// Установка через sc.exe create "MyService" binPath="путь_к_exe"
3. Современные альтернативы:
- Hangfire / Quartz.NET: Для сложного планирования фоновых заданий.
- Azure Functions / AWS Lambda: Для бессерверного выполнения задач.
- Worker Services в .NET: Шаблон для создания длительно работающих служб с поддержкой контейнеризации (Docker).
Ключевые аспекты: устойчивость к ошибкам, корректное логирование, поддержка graceful shutdown и конфигурируемость.
Ответ 18+ 🔞
Слушай, вот реально приходилось городить всякие фоновые штуки, которые тихо себе работают, пока все спят. Ну, там почту рассылать, очереди обрабатывать, кэш подчищать — обычная рутина, блядь.
1. Фоновые службы в ASP.NET Core (BackgroundService): Это когда тебе надо, чтобы внутри самого веб-приложения что-то тикало, как часы. Удобно, не надо отдельный сервис городить.
public class TimedHostedService : BackgroundService
{
private readonly ILogger<TimedHostedService> _logger;
private readonly IServiceScopeFactory _scopeFactory;
public TimedHostedService(ILogger<TimedHostedService> logger, IServiceScopeFactory scopeFactory)
{
_logger = logger;
_scopeFactory = scopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service running.");
using PeriodicTimer timer = new(TimeSpan.FromSeconds(5));
try
{
while (await timer.WaitForNextTickAsync(stoppingToken))
{
await using (var scope = _scopeFactory.CreateAsyncScope())
{
var scopedProcessor = scope.ServiceProvider
.GetRequiredService<IScopedProcessingService>();
await scopedProcessor.DoWorkAsync(stoppingToken);
}
}
}
catch (OperationCanceledException)
{
_logger.LogInformation("Timed Hosted Service is stopping.");
}
}
}
// Регистрация в Program.cs: builder.Services.AddHostedService<TimedHostedService>();
Вот смотри, суть в чём: создаёшь таймер, и он каждые пять секунд, как долбоёб назойливый, дёргает твою логику. А IServiceScopeFactory — это чтобы зависимости правильно резолвить, а то без него влетит в дедлок, как курьер в лифт с зеркалами.
2. Windows Services (старые добрые NT Services): Это уже для монстров, которые должны висеть в системе всегда, даже когда пользователь не залогинен. Типа демонов на Windows.
using System.ServiceProcess;
public class MyWindowsService : ServiceBase
{
private BackgroundWorker _worker;
protected override void OnStart(string[] args)
{
_worker = new BackgroundWorker();
_worker.DoWork += (s, e) => { /* Долгая фоновая работа */ };
_worker.RunWorkerAsync();
}
protected override void OnStop()
{
_worker?.CancelAsync();
// Освобождение ресурсов
}
}
// Установка через sc.exe create "MyService" binPath="путь_к_exe"
Честно? Старая школа. Запустил — и забыл. Пока кто-то вручную не остановит или система не грохнется. Установка через консоль — отдельный квест на потерю нервных клеток, ёпта.
3. Ну и куда же без модных альтернатив:
- Hangfire / Quartz.NET: Это когда тебе нужно не просто "раз в пять секунд", а сложное расписание, вроде "в последнюю пятницу месяца в 3:15 ночи, но только если нет затмения". Мощные штуки, но и возни с ними — овердохуища.
- Azure Functions / AWS Lambda: Бессерверное — звучит круто, пока не начнёшь считать деньги за каждый вызов. Но для спорадических задач — вообще огонь, не надо париться об инфраструктуре.
- Worker Services в .NET: Свежая фишка, специально для создания долгоживущих служб, которые можно в Docker запихнуть и забыть, как страшный сон.
Главное во всём этом, чувак — не накосячить с обработкой ошибок и остановкой. Чтобы служба не сдохла молча, как муха в янтаре, а хотя бы в лог написала, от чего кончилась. И чтобы её можно было аккуратно остановить, а не убивать через Task Manager, как последнего пидораса. Всё остальное — уже детали.