netcore 后台任务 指定每天某一时间执行任务

简单的实现每天运行一次的定时器,执行时间放在数据库为了用户能方便随意修改。

一、使用System.Threading.Timer

实现方式,通过backgroundService后台任务,放入每1小时查看数据库中的时间一次,如果执行时间正好在1小时之内,就使用System.Threading.Timer执行一次任务。

 

1、在Startup.cs注册两个服务

  services.AddScoped<AutoSubmitApplicationService>();           

services.AddHostedService<BackgroundApplySubmitService>();

2、BackgroundApplySubmitService

 public class BackgroundApplySubmitService : BackgroundService
    {
        private readonly ILogger<BackgroundApplySubmitService> _logger;
        private readonly AutoSubmitApplicationService _applictionService;
        private Timer _timer;

        public BackgroundApplySubmitService(ILogger<BackgroundApplySubmitService> logger, IServiceScopeFactory factory)
        {
            _logger = logger;
            _applictionService = factory.CreateScope().ServiceProvider.GetRequiredService<AutoSubmitApplicationService>(); ;
        }
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
        //每一小时执行一次
_timer = new Timer(_applictionService.GetTimeOfApplictionSubmit, null, 10000,3600000); return Task.CompletedTask; } public override void Dispose() { base.Dispose(); _timer?.Dispose(); } }

3、AutoSubmitApplicationService 

 public class AutoSubmitApplicationService
    {
        private readonly DataContext db;
        private readonly ILogger<AutoSubmitApplicationService> _logger;
        public AutoSubmitApplicationService(DataContext dbContext, ILogger<AutoSubmitApplicationService> logger)
        {
            _logger = logger;
            db = dbContext;
        }

        public void GetTimeOfApplictionSubmit(object o)
        {
            var item = db.SetAutoApplication.FirstOrDefault();
            var isStartUp = item?.IsStartUp ?? false;
            var gotoTime = item?.GotoTime ?? "";

            if (isStartUp &&  Regex.IsMatch(gotoTime, @"^\d{2}:\d{2}$")) 
            {
                var arrtime = gotoTime.Split(":").Select(x => Convert.ToDouble(x)).ToArray();
                var h = arrtime[0];
                var m = arrtime[1];
                DateTime oneOClick = DateTime.Today.AddHours(h).AddMinutes(m);
                DateTime now = DateTime.Now;
                var due = (int)((oneOClick - now).TotalMilliseconds);
                Console.WriteLine(due);
                if ((due >= 0 && due <= 3600000))
                {
                    //在一个小时内执行任务
                    var task = new System.Threading.Timer(DoWord);
                    task.Change(due, 0);
                }
            }
        }

        private void DoWord(object o)
        {
            Console.WriteLine("一天只执行一次");
        }

    }

 

实现完毕

二、使用

System.Timers.Timer
public class BackgroundApplySubmitService : BackgroundService
    {
        private readonly ILogger<BackgroundApplySubmitService> _logger;
        private readonly AutoSubmitApplicationService _applictionService;
        private readonly IServiceScopeFactory _factory;
        private Timer timer;
        private System.Timers.Timer doworkTimer;
        private DataContext db;
        private string intervaltime;
        private static int i=0;
        public BackgroundApplySubmitService(ILogger<BackgroundApplySubmitService> logger, IServiceScopeFactory factory)
        {
            _logger = logger;
            _factory = factory;
            _applictionService = _factory.CreateScope().ServiceProvider.GetRequiredService<AutoSubmitApplicationService>();
        }
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            intervaltime = "01:00";//默认一小时

            Console.WriteLine("定时器启动");

             //每1分钟执行一次
            timer = new Timer(MyIntervalometer, null, 1000, 1000);
        //开始就执行一次 StartupTime();
return Task.CompletedTask; } public void MyIntervalometer(object o) { Console.WriteLine(++i); //从数据库中取间隔 string db_intervaltime = ""; using (var scope = _factory.CreateScope()) { db = scope.ServiceProvider.GetRequiredService<DataContext>(); db_intervaltime = db.SetAutoApplication.First().intervalTime; } if (db_intervaltime != intervaltime) { i = 0; doworkTimer?.Stop(); intervaltime = db_intervaltime; StartupTime(); } } /// <summary> /// /// </summary> /// <param name="time">格式:分:秒 (01:30)</param> public void StartupTime() { Console.WriteLine($"间隔运行时间:{intervaltime}"); var item = intervaltime.Split(":").Select(x => Convert.ToInt32(x)).ToArray(); var interval = (item[0]*60+item[1]) * 1000; doworkTimer =new System.Timers.Timer(); doworkTimer.Interval = interval; doworkTimer.AutoReset = true; doworkTimer.Enabled = true; doworkTimer.Elapsed += DoworkTimer_Elapsed; } private void DoworkTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { Console.WriteLine("间隔时间后执行一次"); } public override void Dispose() { base.Dispose(); timer?.Dispose(); doworkTimer?.Stop(); doworkTimer?.Dispose(); } }

 三、直接一点,每分钟运行一次去判断

timer = new Timer(task, null, 1000, 60000);

task

public void MyTimer(object o)
        {
            var item = db.SetAutoApplication.FirstOrDefault();
            if (item != null)
            {
                var isStartUp = item.IsStartUp;
                var gotoTime = item.GotoTime;
                if (isStartUp && Regex.IsMatch(gotoTime, @"^\d{2}:\d{2}$"))
                {
                    var hm = gotoTime.Split(":").Select(x => Convert.ToInt32(x)).ToArray();
                    var now = DateTime.Now;
                    if (now.Hour == hm[0] && now.Minute == hm[1])
                    {
                        DoWord();
                    }
                }
            }
        }

 

posted @ 2021-08-19 21:05  lunawzh  阅读(1321)  评论(0编辑  收藏  举报