ClientStatusUpdateBackgroundService.cs 2.96 KB
using HHECS.DAQShared.Models;

namespace HHECS.DAQServer.Services
{
    public class ClientStatusUpdateBackgroundService : BackgroundService
    {
        private readonly IFreeSql _freeSql;
        private readonly DataCacheService _dataCacheService;
        private readonly ILogger<ClientStatusUpdateBackgroundService> _logger;
        private readonly int _limit = 1000;

        public ClientStatusUpdateBackgroundService(IFreeSql freeSql, DataCacheService dataCacheService, ILogger<ClientStatusUpdateBackgroundService> logger)
        {
            _freeSql = freeSql;
            _dataCacheService = dataCacheService;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    //每10秒执行一次
                    await Task.Delay(10000, stoppingToken);
                    using var clientStatusRepository = _freeSql.GetRepository<ClientStatus>();
                    var temps = _dataCacheService.ClientStatusDictionary.Where(x => x.Value >= DateTime.Now.AddMinutes(-5)).ToList();

                    //按照设定的数量进行分组
                    var groups = new List<List<KeyValuePair<Guid, DateTime>>>();
                    for (int i = 0; i < temps.Count; i += _limit)
                    {
                        var group = temps.Skip(i).Take(_limit).ToList();
                        groups.Add(group);
                    }

                    //待更新数据
                    var waitUpdateItem = new List<ClientStatus>();
                    foreach (var group in groups)
                    {
                        var allClientKeys = group.Select(x => x.Key).ToList();
                        var clientStatusItems = clientStatusRepository.Where(x => allClientKeys.Contains(x.ClientKeys)).ToList();
                        foreach (var item in clientStatusItems)
                        {
                            var temp = group.Find(x => x.Key == item.ClientKeys);
                            if (item.LastSeenDate < temp.Value)
                            {
                                clientStatusRepository.Attach(item);
                                item.LastSeenDate = temp.Value;
                                waitUpdateItem.Add(item);
                            }
                        }
                    }

                    //分批更新
                    for (int i = 0; i < waitUpdateItem.Count; i += _limit)
                    {
                        var temp2s = waitUpdateItem.Skip(i).Take(_limit).ToList();
                        clientStatusRepository.Update(temp2s);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"[{nameof(ClientStatusUpdateBackgroundService)}]线程异常:{ex.Message}");
                }
            }
        }
    }
}