注册托管服务+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; });