using NCrontab; using ReserveManagementSystemApi.Services; namespace ReserveManagementSystemApi.HostedService { public class HostedImportExportClosed : BackgroundService { private readonly IConfiguration _config; private readonly IServiceScopeFactory _scopeFactory; private readonly CrontabSchedule _schedule; private DateTime _nextRun; public const string DefaultCronPattern = "15 19 * * 0-6"; private CancellationToken _cancellationToken; public HostedImportExportClosed(IConfiguration config, IServiceScopeFactory scopeFactory) { _config = config; _scopeFactory = scopeFactory; try { _schedule = CrontabSchedule.Parse(_config.GetSection("HostedServices").GetSection("ImportExportClosedCronSchedule").Value); } catch (Exception ex) { Log.Error(ex, "Failure parsing crontab in appsettings."); _schedule = CrontabSchedule.Parse(DefaultCronPattern); } _nextRun = _schedule.GetNextOccurrence(DateTime.Now); } protected override async Task ExecuteAsync(CancellationToken cancellationToken) { Log.Information("Hosted ImportExportClosed is starting."); Log.Information($"The import export closed job will run at {_nextRun:M/d/yyyy HH:mm:ss tt}"); _cancellationToken = cancellationToken; try { await ImportExportScheduler(cancellationToken); } catch (TaskCanceledException ex) when (_cancellationToken.IsCancellationRequested) { Log.Information(ex, "Hosted ImportExportClosed shut down normally."); } catch (Exception ex) { Log.Error(ex, "Error trying to startup main thread for Hosted ImportExportClosed"); } Log.Information("Hosted ImportExportClosed is stopping."); } private async Task ImportExportScheduler(CancellationToken cancellationToken) { do { if (DateTime.Now > _nextRun) { using (var scope = _scopeFactory.CreateScope()) { await scope.ServiceProvider.GetRequiredService().RunImportExportClosed(_cancellationToken); } _nextRun = _schedule.GetNextOccurrence(DateTime.Now); } await Task.Delay(5000, cancellationToken); //5 seconds delay } while (!cancellationToken.IsCancellationRequested); } } }