注册托管服务+timer实现简单定时任务

1.创建服务类
  public class TimerService : IHostedService, IDisposable
  {
      /// <summary>
      /// 定义定时器
      /// </summary>
      private static System.Threading.Timer _timer;

      private static int _count = 0;
      /// <summary>
      /// 销毁
      /// </summary>
      public void Dispose()
      {
          _timer.Dispose();
      }

      /// <summary>
      /// 开始
      /// </summary>
      /// <param name="cancellationToken"></param>
      /// <returns></returns>
      public Task StartAsync(CancellationToken cancellationToken)
      {
          //5秒执行一次
          var newTimer = new System.Threading.Timer(OnTimedEvent, null, 0, 1000);

          return Task.CompletedTask;
          //两种定时器
          //_timer = new System.Timers.Timer(1000);
          //_timer.Elapsed += OnTimedEvent;
          //_timer.Enabled = true;
          //Console.WriteLine("定时器已启动。按任意键停止...");
          //Console.ReadKey();
          //_timer.Enabled = false;
          //_timer.Dispose();
      }


      /// <summary>
      /// 
      /// </summary>
      /// <param name="state"></param>

      private  void OnTimedEvent(object? state)
      {
          _count++;
          Console.WriteLine($"定时器触发第 {_count} 次,时间:{DateTime.Now}");
      }

      /// <summary>
      /// 停止
      /// </summary>
      /// <param name="cancellationToken"></param>
      /// <returns></returns>
      /// <exception cref="NotImplementedException"></exception>

      public Task StopAsync(CancellationToken cancellationToken)
      {
          // 停止定时器
          _timer?.Change(Timeout.Infinite, 0);
          return Task.CompletedTask;
      }
  }

2.注册服务

//注册定时服务,如果要获取Service层的对象,可以放到最底下
builder.Services.AddHostedService<TimerService>();

 


3.启动查看

 





4.问题点:k8s有四台节点的话, 会同时跑这个定时任务,考虑是否要限流,限流代码

//可按照自己的项目内redis代码加分布式锁的方式
await _cache.GetDistributedLockAsync<int>("分布式redis锁", 60, async () => { var key = "限流redis key"; var time = await _cache.GetAsync<string>(key); if (!string.IsNullOrWhiteSpace(time)) { var date = Convert.ToDateTime(time); //5s内只会执行一个逻辑 if ((DateTime.Now - date).TotalSeconds < 5) { return -1; } } await _cache.SetAsync(key, DateTime.Now, 2); //执行业务 return 1; });

 

posted @ 2025-01-05 17:19  十一一十三  阅读(15)  评论(0)    收藏  举报