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();
                    }
                }
            }
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM