首页 > 解决方案 > ASP.Net按倍数执行计划任务的方法

问题描述

来自本网站的作者:

https://codinginfinite.com/creating-scheduler-task-seconds-minutes-hours-days/

我可以在 24 小时内定义任务执行参数来运行我的方法,但是我在代码中看不到任何逻辑,我清楚地知道为什么它会多次触发我的方法。问题是我的方法应该只执行一次,但从指定时间开始每分钟执行一次,它实际上在不到一分钟的时间内执行了 20 多次。我试过改变参数和重复间隔,但似乎没有什么能解决这个问题,而且不同的执行间隔总是比指定的多次触发该方法 - 即类似地,间隔 5 分钟,但我在一分钟内收到 30 多个订单,而我希望每 5 分钟执行不超过一个订单。

关于为什么此代码会发生这种情况的任何想法?

这是服务类:

public class SchedulerService
    {                
        private static SchedulerService _instance;
        private List<Timer> timers = new List<Timer>();
        private SchedulerService() { }
        public static SchedulerService Instance => _instance ?? (_instance = new SchedulerService());
        public void ScheduleTask(int hour, int min, double intervalInHour, Action task)
        {            
            DateTime now = DateTime.Now;
            DateTime firstRun = new DateTime(now.Year, now.Month, now.Day, hour, min, 0, 0);

            if (now > firstRun)
            {
                firstRun = firstRun.AddDays(1);
            }
            
            TimeSpan timeToGo = firstRun - now;
            if (timeToGo <= TimeSpan.Zero)
            {
                timeToGo = TimeSpan.Zero;
            }   
            
            var timer = new Timer(x =>
            {
                task.Invoke();
            }, null, timeToGo, TimeSpan.FromHours(intervalInHour));
            timers.Add(timer);            
        }
    }

这是调度程序类:

public class Scheduler
    {
        public static void IntervalInSeconds(int hour, int sec, double interval, Action task)
        {
            interval = interval / 3600;
            SchedulerService.Instance.ScheduleTask(hour, sec, interval, task);
        }
        public static void IntervalInMinutes(int hour, int min, double interval, Action task)
        {
            interval = interval / 60;
            SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
        }
        public static void IntervalInHours(int hour, int min, double interval, Action task)
        {
            SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
        }
        public static void IntervalInDays(int hour, int min, double interval, Action task)
        {
            interval = interval * 24;
            SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
        }
    }

使用定义的开始时间参数和重复间隔在页面加载时实例化:

    protected void Page_Load(object sender, EventArgs e)
    {
        Scheduler.IntervalInMinutes(20, 15, 1,
        () => {
            buyOrder();
        });
    }

20:15,调用这个方法,每分钟重复一次:

    private static void buyOrder()
    {
        //This is only a basic POST method
    }

结果:

如前所述,我得到了在 <1 分钟内执行的多个订单。

标签: asp.nettask

解决方案


问题似乎不在代码中,而在于您在Page_Load事件中运行调度指令这一事实。

我有根据的猜测是,如果您对此进行调试,您会发现您的Page_Load事件会触发多次,这会导致安排多个作业。

发生这种情况的原因有很多(比如多个事件处理程序、Ajax 请求,甚至是通过代码本身进行调试的行为,因为如果某些浏览器没有收到及时的响应,它们会重新发出请求),但底线是您应该重新考虑触发调度的方式/位置。


推荐阅读