ASP.Net定时任务的倍数执行方式
ASP.Net Scheduled Task Executing Method by Multiples
来自此站点的作者信用:
https://codinginfinite.com/creating-scheduler-task-seconds-minutes-hours-days/
我可以在 运行 我的方法中定义 24 小时内的任务执行参数,但我看不到代码中的任何逻辑我都清楚为什么它会多次触发我的方法.问题是我的方法应该只执行一次,但从指定时间开始每分钟执行一次,实际上在不到一分钟的时间内执行了 20 多次。我试过改变参数和重复间隔,但似乎没有什么能解决问题,不同的执行间隔总是比指定的间隔多次触发该方法 - 即类似地,5 分钟间隔,但我在一分钟内得到 30 多个订单,而我预计每 5 分钟执行的订单不会超过一个..
关于此代码为何会发生这种情况的任何想法?
这是服务 class:
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);
}
}
这是调度器class:
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 分钟内执行了多个订单。
问题似乎不在代码中,而是您是 运行 Page_Load
事件中的调度指令这一事实。
我有根据的猜测是,如果您对此进行调试,您会发现您的 Page_Load
事件多次触发,这会导致安排多个作业。
发生这种情况的原因有很多(例如多个事件处理程序、Ajax 请求,甚至是通过代码本身进行调试的行为,因为如果某些浏览器没有收到请求,它们会重新发出请求及时响应)但最重要的是你应该重新考虑 how/where 你触发了调度。
来自此站点的作者信用:
https://codinginfinite.com/creating-scheduler-task-seconds-minutes-hours-days/
我可以在 运行 我的方法中定义 24 小时内的任务执行参数,但我看不到代码中的任何逻辑我都清楚为什么它会多次触发我的方法.问题是我的方法应该只执行一次,但从指定时间开始每分钟执行一次,实际上在不到一分钟的时间内执行了 20 多次。我试过改变参数和重复间隔,但似乎没有什么能解决问题,不同的执行间隔总是比指定的间隔多次触发该方法 - 即类似地,5 分钟间隔,但我在一分钟内得到 30 多个订单,而我预计每 5 分钟执行的订单不会超过一个..
关于此代码为何会发生这种情况的任何想法?
这是服务 class:
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);
}
}
这是调度器class:
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 分钟内执行了多个订单。
问题似乎不在代码中,而是您是 运行 Page_Load
事件中的调度指令这一事实。
我有根据的猜测是,如果您对此进行调试,您会发现您的 Page_Load
事件多次触发,这会导致安排多个作业。
发生这种情况的原因有很多(例如多个事件处理程序、Ajax 请求,甚至是通过代码本身进行调试的行为,因为如果某些浏览器没有收到请求,它们会重新发出请求及时响应)但最重要的是你应该重新考虑 how/where 你触发了调度。