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)