using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Background; /// /// Сервис для фонового выполнения работы /// public class BackgroundWorker : BackgroundService { private static readonly TimeSpan executePeriod = TimeSpan.FromSeconds(10); private static readonly TimeSpan minDelay = TimeSpan.FromSeconds(2); private readonly IServiceProvider serviceProvider; public WorkStore WorkStore { get; } = new WorkStore(); public Work? CurrentWork; public Exception? MainLoopLastException { get; private set; } = null; public BackgroundWorker(IServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; } protected override async Task ExecuteAsync(CancellationToken token) { while (!token.IsCancellationRequested) { try { var work = WorkStore.GetNext(); if (work is null) { await Task.Delay(executePeriod, token); continue; } CurrentWork = work; using var scope = serviceProvider.CreateScope(); var result = await work.Start(scope.ServiceProvider, token); if (!result) WorkStore.Felled.Add(work); else WorkStore.Done.Add(work); CurrentWork = null; await Task.Delay(minDelay, token); } catch (Exception ex) { MainLoopLastException = ex; var mainLoopLastException = $"BackgroundWorker " + $"MainLoopLastException: \r\n" + $"date: {DateTime.Now:O}\r\n" + $"message: {ex.Message}\r\n" + $"inner: {ex.InnerException?.Message}\r\n" + $"stackTrace: {ex.StackTrace}"; Trace.TraceError(mainLoopLastException); } } } }