using Microsoft.Extensions.Hosting; namespace Service; /// /// 周期性账单后台服务 /// public class PeriodicBillBackgroundService( IServiceProvider serviceProvider, ILogger logger ) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { logger.LogInformation("周期性账单后台服务已启动"); while (!stoppingToken.IsCancellationRequested) { try { var now = DateTime.Now; // 计算下次执行时间(每天早上6点) var nextRun = now.Date.AddHours(6); if (now >= nextRun) { nextRun = nextRun.AddDays(1); } var delay = nextRun - now; logger.LogInformation("下次执行周期性账单检查时间: {NextRun}, 延迟: {Delay}", nextRun.ToString("yyyy-MM-dd HH:mm:ss"), delay); await Task.Delay(delay, stoppingToken); if (stoppingToken.IsCancellationRequested) break; // 执行周期性账单检查 using (var scope = serviceProvider.CreateScope()) { var periodicService = scope.ServiceProvider.GetRequiredService(); await periodicService.ExecutePeriodicBillsAsync(); } } catch (OperationCanceledException) { logger.LogInformation("周期性账单后台服务已取消"); break; } catch (Exception ex) { logger.LogError(ex, "周期性账单后台服务执行出错"); // 出错后等待1小时再重试 await Task.Delay(TimeSpan.FromHours(1), stoppingToken); } } logger.LogInformation("周期性账单后台服务已停止"); } }