QWorker-不仅仅是一个线程池

    首先,我们承认QWorker是一个线程池,毕竟它的每个工作者一就是一个线程。

    其次,QWorker不仅仅是一个线程池,这意味着它做的工作远远超过线程池的管理,而且牵涉到完整的作业调度。QWorker基于作业的视角,让其功能变得与众不同。

    从作业的视角来看,我们模拟一个场景:

    1、你安排你家孩子立刻去买瓶酱油,这实际上就是你安排了一项立即在后台执行的作业,在QWorker中用Post方法实现。

    2、你告诉你家孩子买完酱油打电话通知你一声,这实际上就是你安排了一项信号作业,当你孩子买完酱油时,会触发一个信号,对应于QWorker的Singal方法,而你可能在收到你孩子买完酱油的通知(Signal信号)后,开始洗菜准备做饭。

    3、你家孩子回来了,你告诉孩子休息半个小时后开饭,这实际上就是安排了一项延迟作业,在QWorker中用Delay方法实现。

    4、吃完饭了,得休息下才能干别的,于是你告诉孩子休息15分钟后,去写作业去,每个小时写半个小时休息半个小时,这实际上安排的是一种延迟重复作业,在QWorker中用At函数来实现,如果你不心痛孩子,不让休息(是不是亲生的呀!),那么在QWorker中可以直接用Post方法实现,指定一个时间间隔。

    5、时光飞逝如电,转眼到了晚上,你告诉孩子9点上床睡觉,这就安排了一个固定时间点的定时作业,在QWorker中用At函数来实现。

    上面的场景模拟的比较简单,我们让其复杂一点,就需要TQJobGroup的介入了:

    你临做菜前,发现酱油没了,于是你让孩子去买,在此期间你安排你爱人继续洗菜切菜,最后才交由你这个大厨烹饪。由于前两项都未完成,因此,你需要等待你孩子买回来酱油和前期其它工作准备就绪。此时,你需要创建一个作业组(TQJobGroup),一个作业是安排孩子买酱油(Add添加作业),另一个作业是要安排爱人洗菜切菜(Add添加作业),做好烹饪前的准备工作,而你现在只能等待前两项工作就绪(WaitFor/MsgWaitFor或通过AfterDone事件异步响应)。在孩子买完酱油,你爱人菜也洗切完成,就等烹饪时(WaitFor/MsgWaitFor返回wrSignaled或者AfterDone事件被调用),做为大厨的你闪亮登场,开始正式烹饪。

    一个TQJobGroup可以顺序执行,也可以并行,但一个作业组只能选择一种方式,但通过多个作业组之间串连,就可以完成最复杂场景的实现。比如Group1是并行的获取某些资源,Group2串行的处理这些资源,然后将结果做为Group3并行处理的基础,依次类推,无穷无尽……

    最后,QWorker中的作业并不象OTL或XE7中的System.Threading一样,是一定在后台线程中执行的。作业可以在后台线程中,或者主线程中执行。就象你安排干活时,可以安排在家里干,也可以安排在外面干一样,但主线程运行的作业肯定要占用主线程的CPU时间片,所以一定不要执行太复杂的任务,以避免出现前台假死一样。

分享到: