轮询作业调度程序的替代方法

时间:2011-06-06 19:43:06

标签: c# .net polling quartz.net job-scheduling

我们在工作中需要一个工作服务器,而我现在正在玩Quartz.net,但创建我自己的想法的想法。至少理解Quartz.net在幕后所做的事情不会影响我理解/更有效地使用它的机会。

所以我的问题是你如何在没有轮询的线程上获得和解雇工作?如果你检查你的'jobstore'需要2分钟才能找到需要解雇的工作,你可以延迟2分钟。如果减少轮询时间,则会增加求职者的压力,但仍然无法获得真正的开始时间。您可以为下一个两分钟段预加载作业,并让线程在剩余时间内休眠,以便它们在适当的时间开始,但如果您的轮询时间很长(删除,重新安排等),这似乎很容易出现问题。我决定用石英来弄清楚它是如何做到的,但我想知道我是否遗漏了一些基本的东西。

编辑:

Kevin最初描述的线程结构似乎就是你应该如何做一个作业服务器。它以最少的开销为您提供最大的灵活性。因为线程对于大多数人来说都是如此(也许只是我)...更简单的轮询示例将在90%的情况下完成工作,代价是失去灵活性和更多开销。

另一方面,除非您使用单个线程执行单个作业,否则无论如何都必须处理线程。也可以去全猪并找出信号。

我也同意Kevin的看法,你在断言你在polling db示例中免费获得的东西并不是免费的。如果它是线程/等待的应用程序,你将像你想要的那样编​​写代码。如果您的轮询数据库作业服务器在作业中间爆炸怎么办?两者都将依靠一些持久的存储来跟踪他们在发生灾难时的状态。

如果将'jobstore'提升到一个抽象级别并且它不是基于正常的ACID(右期?)数据库,该怎么办?现在我相信很多你的'免费'东西基于不再可用(交易?)。

1 个答案:

答案 0 :(得分:2)

您将创建一个要触发的任务队列,按时间排序(从最短到最长时间)。将有一个线程等待队列头部的时间。当该时间到期时,您删除该项目并启动该任务。如果它是一个重复的任务重新计算并重新排队。

唯一棘手的事情是线程应该根据某些条件变量等待。如果队列头部改变,则可以发信号通知条件变量。通常使用条件变量,您可以判断它是否已发出信号并且超时已到期。因此,如果发出信号,则只需重新等待新的头部时间,否则超时表示是时候在队列的头部运行任务了。

此解决方案意味着您只有一个线程来管理任务,而且它不是轮询。

编辑:

我将更新我的解决方案,指出编写自己的调度程序可能不是一个好主意,因为石英是一个非常好的解决方案。此外,我认为每秒轮询都有点矫枉过正,因为工作通常是按分钟进行,而不是每秒进行一次。例如,您是否真的关心工作是在12:00:05开始,还是在12:00:00足够好?无论如何,您可以参数化轮询以满足所需的粒度级别。