我正在实现一个调度与以下要求。在调度任务时,我在数据库作业表中添加一个条目,其中包含一个CRON表达式和一个标记,以标识需要在代码中运行的方法。
我正在使用.NET Core提供的BackgroundService定期从我的作业表中获取数据。我希望能够运行所需的代码使用的cron表达式和标记,我已经提到。
我的预期行为示例如下。
public class SchedulerBackgroundService : BackgroundService
{
private readonly IDatabaseService _databaseService;
public SchedulerBackgroundService(IDatabaseService databaseService)
{
this._databaseService = databaseService;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var jobsFromDb = await _databaseService.GetActiveJobs();
try
{
foreach (var job in jobsFromDb)
{
var schedule = NCrontab.CrontabSchedule.Parse(job.CronExpression);
var nextOccurance = schedule.GetNextOccurrence(DateTime.Now);
if (DateTime.Now > nextOccurance)
{
if (job.Tag == "First")
{
ProcessFirst();
}
else if (job.Tag == "Second")
{
ProcessSecond();
}
}
await Task.Delay(5000, stoppingToken); //5 seconds delay
}
}
catch (Exception ex)
{
// log
}
}
}
}
如果条件DateTime.Now > nextOccurance始终为false,则这将不起作用,因为nextOccurance是使用DateTime计算的。现在
有没有其他方法可以使其工作,而不将nextOccurrence作为数据库的列之一存储。
我看过一些建议使用Quartz等库的文章,但大多数文章都提供了一个示例,即只调度一个CRON表达式始终不变的作业。
我想要一个单一的后台服务来处理所有类型的处理。所以CRON表达式不能是常量。请提供有关实现此功能的任何有用建议。谢谢
1条答案
按热度按时间lhcgjxsq1#
有没有其他方法可以使其工作,而不将nextOccurrence作为数据库的列之一存储。
将 last 事件存储在数据库中,并将其传递给
GetNextOccurrence
。