我正在寻找一种表达方式,可以通过Hangfire在特定的星期几以及星期几创建有效的每月定期工作,
RecurringJob.AddOrUpdate有两种创建Cron expresison的方法(通过hangfire和字符串表达式本身来创建helper类)helper类包含Monthly表达式的方法,但问题是它仅具有日期和时间数的参数,以及我一直在寻找有效的表达方式,但发现以下主题:
Hangfire Cron expressions are not valid 我已经尝试找到一种有效的方法来创建表达目的的表达式,但是当我尝试使用http://cron.schlitt.info或{{3 }}可能由hangfire用于解析表达式):
1-7 first week
8-14 second week
15-21 third week
22-28 forth week
29-31 fifth week
答案 0 :(得分:1)
根据我的理解,cron表达式不能包含星期数,请参阅下面的cron标准:
minute (0-59)
hour (0-23)
day of the month (1-31)
month of the year (1-12)
day of the week (0-6 with 0=Sunday)
话虽这么说,但不了解您的确切情况,这里有2种可能的解决方案:
解决方案1:
忽略周数并计算天数:
RecurringJob.AddOrUpdate(() => Execute(), "0 6 1,2,3,4,5,6,7 * *");// Run every morning @ 6 if day between 1 and 7
RecurringJob.AddOrUpdate(() => Execute(), "0 6 8,9,10,11,12,13,14 * *");// Run every morning @ 6 if day between 8 and 14
RecurringJob.AddOrUpdate(() => Execute(), "0 6 15,16,17,18,19,20,21 * *");// Run every morning @ 6 if day between 15 and 21
RecurringJob.AddOrUpdate(() => Execute(), "0 6 22,23,24,25,26,27,28 * *");// Run every morning @ 6 if day between 22 and 28
RecurringJob.AddOrUpdate(() => Execute(), "0 6 29,30,31 * *");// Run every morning @ 6 if day between 29 and 31
解决方案2:
根据您的业务需求也可以解决问题的伪代码:
每天运行一次的主要作业(如果适用)将排队其他作业。
static void Main(string[] args)
{
RecurringJob.AddOrUpdate(() => Execute(), "0 6 * * *");// Run every morning @ 6
}
private static void Execute()
{
int currentWeekNumber = GetWeekNumberOfMonth(DateTime.Now);
int dayNumber = (int)DateTime.Now.DayOfWeek;
if ((currentWeekNumber == 1) && (dayNumber == (int)DayOfWeek.Wednesday))
BackgroundJob.Enqueue(() => Console.WriteLine("Week 1 Job"));
if ((currentWeekNumber == 2) && (dayNumber == (int)DayOfWeek.Monday))
BackgroundJob.Enqueue(() => Console.WriteLine("Week 2 Job"));
if ((currentWeekNumber == 3) && (dayNumber == (int)DayOfWeek.Thursday))
BackgroundJob.Enqueue(() => Console.WriteLine("Week 3 Job"));
if ((currentWeekNumber == 4) && (dayNumber == (int)DayOfWeek.Friday))
BackgroundJob.Enqueue(() => Console.WriteLine("Week 4 Job"));
}
private static int GetWeekNumberOfMonth(DateTime date)
{
date = date.Date;
DateTime firstMonthDay = new DateTime(date.Year, date.Month, 1);
DateTime firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
if (firstMonthMonday > date)
{
firstMonthDay = firstMonthDay.AddMonths(-1);
firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
}
return (date - firstMonthMonday).Days / 7 + 1;
}