diff --git a/YD_Event.Application/Event/EventStatusUpdateService.cs b/YD_Event.Application/Event/EventStatusUpdateService.cs index 0ff9519..e455c7e 100644 --- a/YD_Event.Application/Event/EventStatusUpdateService.cs +++ b/YD_Event.Application/Event/EventStatusUpdateService.cs @@ -8,13 +8,14 @@ namespace YD_Event.Application.Event; /// /// 赛事状态自动更新后台服务 -/// 每5分钟执行一次,自动更新赛事状态 +/// 每10秒执行一次,自动更新赛事状态 /// public class EventStatusUpdateService : BackgroundService { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; private readonly PeriodicTimer _timer; + private int _executionCount = 0; public EventStatusUpdateService( IServiceProvider serviceProvider, @@ -22,12 +23,12 @@ public class EventStatusUpdateService : BackgroundService { _serviceProvider = serviceProvider; _logger = logger; - _timer = new PeriodicTimer(TimeSpan.FromMinutes(5)); + _timer = new PeriodicTimer(TimeSpan.FromSeconds(10)); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - _logger.LogInformation("赛事状态自动更新服务已启动,每5分钟执行一次"); + _logger.LogInformation("赛事状态自动更新服务已启动,每10秒执行一次"); try { @@ -57,12 +58,46 @@ public class EventStatusUpdateService : BackgroundService var now = DateTime.Now; var eventsToUpdate = new List(); + + _executionCount++; + + // 每执行6次(约1分钟)做一次全量检查,其他时候只检查时间窗口内的赛事 + var isFullCheck = _executionCount % 6 == 1; + + List candidateEvents; - var allEvents = await repository.AsQueryable() - .Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable) - .ToListAsync(stoppingToken); + if (isFullCheck) + { + _logger.LogDebug("执行全量赛事状态检查..."); + candidateEvents = await repository.AsQueryable() + .Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable) + .ToListAsync(stoppingToken); + } + else + { + // 优化查询:只查询可能需要更新状态的赛事 + // 逻辑:只查询那些当前时间接近关键时间点(报名开始/结束、比赛开始/结束)的赛事 + // 设置一个时间窗口:当前时间前后各1分钟,这样只会处理即将或刚发生状态变化的赛事 + var timeWindow = TimeSpan.FromMinutes(1); + var windowStart = now.Add(-timeWindow); + var windowEnd = now.Add(timeWindow); - foreach (var evt in allEvents) + candidateEvents = await repository.AsQueryable() + .Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable) + .Where(e => + // 报名开始时间在时间窗口内 + (e.RegistrationStartTime >= windowStart && e.RegistrationStartTime <= windowEnd) || + // 报名结束时间在时间窗口内 + (e.RegistrationEndTime >= windowStart && e.RegistrationEndTime <= windowEnd) || + // 比赛开始时间在时间窗口内 + (e.MatchStartTime >= windowStart && e.MatchStartTime <= windowEnd) || + // 比赛结束时间在时间窗口内 + (e.MatchEndTime >= windowStart && e.MatchEndTime <= windowEnd) + ) + .ToListAsync(stoppingToken); + } + + foreach (var evt in candidateEvents) { var newStatus = CalculateEventStatus(evt, now); if (evt.EventStatus != newStatus)