我有一个相当具体的问题,根据该任务的配置,找出计算程序中的“任务”下次运行时间的最佳方法。
从配置此“任务”的一些事物的定义开始。首先,一个看起来很像框架的枚举DayOfWeek
枚举,我称之为DaysOfWeek
并将其标记为FlagsAttribute
表明它可以是其倍数:
[Flags]
public enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
其次,具有适当属性的相关类以及我尝试实现的方法:
public class WeeklySchedule
{
public DaysOfWeek DaysToRun { get; set; }
public TimeSpan TimeToRun{ get; set; }
public override DateTime CalculateNextRunTime(DateTime lastRun)
{
// Here's what im trying to implement
}
}
要求应该很明显
- 如果 DaysToRun 是今天,但 TimeToRun 今天已经过去,则返回下一个时间/天
- 如果今天不包含在 DaysToRun 中,则查找下一天/时间来跑步
显然,我周一只是在放屁,因为我无法找到一种有效的方法来计算这个,缺少ShouldExecuteToday()
方法,然后是FindNextExecutionDay()
等等(也许这是正确的方法......)
Edit:好吧,周末的脑雾正在消散,这就是我到目前为止的情况。如果有人可以对此进行改进,我们将不胜感激:
首先,我将两个枚举的映射放入类的静态成员中,我知道我可以按照 @DorCohen 的示例从一个枚举到另一个枚举,但这让我感到恶心。
private static Dictionary<DayOfWeek, DaysOfWeek> DayToDaysMap
= new Dictionary<DayOfWeek, DaysOfWeek>()
{
{DayOfWeek.Monday, DaysOfWeek.Monday},
{DayOfWeek.Tuesday, DaysOfWeek.Tuesday},
{DayOfWeek.Wednesday, DaysOfWeek.Wednesday},
{DayOfWeek.Thursday, DaysOfWeek.Thursday},
{DayOfWeek.Friday, DaysOfWeek.Friday},
{DayOfWeek.Saturday, DaysOfWeek.Saturday},
{DayOfWeek.Sunday, DaysOfWeek.Sunday},
};
然后这个方法来确定是否应该在某一天运行:
private bool ShouldRunOn(DateTime now)
{
var days = DayToDaysMap[now.DayOfWeek];
// If the schedule is not set for the specified day, return false
if (!this.DaysToRun.HasFlag(days))
return false;
// Schedule should run on specified day, just determine if it is in the past
return this.TimeOfDay > now.TimeOfDay;
}
那么实现就变成了; “我今天可以跑步吗”,如果不能的话,“提前 6 天,看看那天我是否可以跑步”。注意参数lastRun
在此实现中未使用,它用于其他实现(例如重复计划)。
public override DateTime CalculateNextRunTime(DateTime lastRun)
{
var now = DateTime.Now;
if (ShouldRunOn(now))
return new DateTime(now.Year,now.Month,now.Day,this.TimeOfDay.Hours,
this.TimeOfDay.Minutes,this.TimeOfDay.Seconds);
for (var i = 1; i < 7; i++)
{
now = now.AddDays(1).Date;
if(ShouldRunOn(now))
return new DateTime(now.Year, now.Month, now.Day,
this.TimeOfDay.Hours, this.TimeOfDay.Minutes, this.TimeOfDay.Seconds);
}
return DateTime.MinValue;
}
欢迎改进!