【发布时间】:2016-11-10 05:16:13
【问题描述】:
我正在创建一个调度程序以在一天中的特定时间触发事件,为此我正在使用 Task.Delay 来启动任务(一次一个,即仅“下一个”计划)最多延迟几天。例如,在周五下午最后一个事件触发后,我将设置下一个事件,即星期一的某个时间,因此它可能是长达 3 天(约 260,000,000 毫秒)的 TimeSpan。
这是可接受的做法吗?我担心这对于生产环境来说不够稳定/强大。
这里有一些sn-ps的代码来描述我放在一起的内容:
private void SetNextEvent()
{
TimeModel next = GetNextScheduledTime();
Debug.WriteLine($"Next schedule [{next.TimeType}]: {next.Time.ToString("yyyy-MM-dd HH:mm:ss")}");
TimeSpan delay = next.Time.Subtract(DateTime.Now);
Task.Run(async () =>
{
await Task.Delay(delay);
FireEvent(next);
});
}
private void FireEvent(TimeModel time)
{
Debug.WriteLine($"Event fired [{time.TimeType}]: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
OnSchedulerEvent?.Invoke(this, new SchedulerEventArgs { ScheduleType = time.TimeType });
if (_running)
SetNextEvent();
}
【问题讨论】:
-
它可以工作吗?我想。第一个想法是如果服务器需要重新启动,你会在没有持久状态的情况下被冲洗掉。有很多调度程序,例如专门为此设计的Quartz。我认为他们将是一个更强有力的选择。
-
如果服务器重新启动,服务将重新启动,它会调用 SetNextEvent,它将返回相同的下一个预定时间,并从那时开始使用 TimeSpan 启动一个任务......我确实考虑过Quartz,不过对于我这两种方法能达到的效果,就显得有点矫枉过正了。
-
假设您的
GetNextScheduledTime的行为在FireEvent 成功执行之前保持不变,您可能需要检查是否存在否定TimeSpan delay。由于您可能会遇到服务器重新启动时时钟超过下一个预定时间的问题。更糟糕的是,它成功地达到了 -1 毫秒,Task.Delay永远不会结束。
标签: c# async-await task-parallel-library