在.NET Core 6中实现多个调度程序的调度器实现

huangapple go评论68阅读模式
英文:

Scheduler Implementation for multiple schedules in .NET Core 6

问题

我正在实现一个调度程序,具有以下要求。
在安排任务时,我会在我的数据库作业表中添加一个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.Now计算的。

是否有其他方法可以使这项工作,而无需将nextOccurence存储为数据库的一列。

我已经阅读了一些文章,建议使用一些库,如Quartz,但它们大多数只提供了一个示例,用于安排单个CRON表达式在整个过程中保持不变的工作。

我希望单个后台服务处理所有种类的处理。因此,CRON表达式不能保持不变。
请帮助提供有关实现此功能的任何有用建议。谢谢

英文:

I am working on implementing a scheduler with the below requirements.
On scheduling a task, I add an entry in my database jobs table with a CRON expression and a tag to identify what method needs to be run in the code.

I am using BackgroundService provided by the .NET Core to periodically fetch the data from my jobs table. I want to be able to run the required code using the cron expression and the tag which I have mentioned.

A sample of my expected behavior would be as below.

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
				}
			}
		}
	}

This would not work as the condition DateTime.Now > nextOccurance would always be false as the nextOccurance is calculated using the DateTime.Now

Is there any other way to make this work without storing the nextOccurence as one of the column to the database.

I have gone through some articles which suggest using some libraries like Quartz, but most of them provide an example just schedule a single job where the CRON expression is constant throughout.

I want a single background service to handle all the kinds of processing. So the CRON expression cannot be constant.
Please help with any useful suggestions on implementing this functionality. Thanks

答案1

得分: 1

最后的出现次数存储在数据库中,并将其传递给GetNextOccurrence

英文:

> Is there any other way to make this work without storing the nextOccurence as one of the column to the database.

Store the last occurence in the database, and pass that to GetNextOccurrence.

huangapple
  • 本文由 发表于 2023年5月29日 22:50:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定