ESBasic 可复用的.NET类库(06) -- 循环任务

系统 1525 0
1. 缘起:

假设我的订单处理系统有这样的需求:将一天 24 小时分为 4 个时段,凌晨 2:15 8:30 采用 A 类型的处理器处理接收到的订单, 8:30 14:00 采用 B 类型的处理器, 14:00 20:00 采用 C 类型的处理器, 20:00 到第二天凌晨 2:15 采用 D 类型的处理器。

即我们的订单处理器需要在任一天的 2:15 8:30 14:00 20:00 这四个时刻发生切换,这就是一个循环切换器所要做的工作。

我设计了 ESBasic.Threading.Application. ICircleTaskSwitcher (循环任务切换器)来对上述例子所要求的切换器进行抽象。 ICircleTaskSwitcher 会在需要切换的时间点触发事件,通知预订者要切换到哪个处理器(或任务)。

循环任务切换器的形象示意图如下:
ESBasic 可复用的.NET类库(06) -- 循环任务切换器 CircleTaskSwitcher

2. 适用场合:

如果满足以下条件,则可以使用 ICircleTaskSwitcher

(1) 循环的周期是一天。

(2) 将一天切分为 N 个( N>=2 )连续的时间段。

(3) 需要在每个时间段的起始进行切换任务。

3 .设计思想与实现

ICircleTaskSwitcher 的设计思路是这样的:

(1) 我们可以使用前面介绍的 ShortTime 来记录每个发生任务切换的时间点。

(2) 使用前面介绍的 Circle 来将所有切换的时间点组成一个“圈”,这样便可循环地取到下一个切换时刻。

(3) 我们可以使用循环引擎 AgileCycleEngine 来对是否到达某个切换时间点进行检测。

(4) 使用泛型参数来抽象切换的任务的类型。

(5) 使用事件通知预订者切换时刻的到来。

ICircleTaskSwitcher 的接口定义如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public interface ICircleTaskSwitcher < TTask >
{
/// <summary>
/// TaskDictionarykey为任务的起始点(hour),value为对应的任务。
/// </summary>
IDictionary < ShortTime ,TTask > TaskDictionary{ get ; set ;}

TTaskCurrentTask{
get ;}

void Initialize();

/// <summary>
/// TaskSwitched当任务发生切换时,触发此事件,事件参数为刚得到控制权的任务。
/// </summary>
event CbGeneric < TTask > TaskSwitched;
}


接口的泛型参数 TTask 代表任务的类型,比如缘起的例子中,该参数可以采用订单处理器接口的类型。

TaskDictionary 属性的键值即是每个切换的时间点,字典的值表示从切换时刻开始要进行的具体任务。

当切换时刻来到时, TaskSwitched 事件将被触发,事件的参数表示从该时刻起要执行的任务对象。

关于 CircleTaskSwitcher 的实现要注意以下几点:

(1) Initialize 方法主要做了三件事情:一是将 N 个切换时间点按照从小到大的顺序进行排序(因为 TaskDictionary 的键不一定是有序的),然后赋值给 Circle ,这样才能做有序的循环;二是找到当前时间所位于的时间段(因为我们可能在任何时刻启动切换器),并设置正确的当前任务;最后就初始化并启动循环引擎。

(2) 在循环引擎的检测方法 EngineAction 中,我们首先判断是否到达了下一个切换时间点,如果是,则触发切换事件。

CircleTaskSwitcher 的源码我们看到,在有了我们前面章节介绍的 Circle ShortTime AgileCycleEngine 等可复用类的帮助下, CircleTaskSwitcher 的实现真是相当的简洁和简单,并且每个类的概念也非常的清晰。这也就是可复用类所带来的好处的一个证明吧。

4. 使用时的注意事项

(1) 由于循环引擎的检测时间间隔是 1 秒――这也是循环引擎能设置的最小检测时间间隔,所以,切换时刻不是非常精确,最多时会有 1 秒的误差。

(2) 关于 TTask 泛型参数,在具体应用中,不一定非得是某个像订单处理器那样的引用类型。比如,我们希望在不同的时间段,给出的商品折扣不一样,那么, TTask 完全可以是 float ,用来记录每个时间段具体的折扣值。

5. 扩展

循环任务切换器 ICircleTaskSwitcher 暂时没有任何扩展。


注:ESBasic源码可到 http://esbasic.codeplex.com/ 下载。
ESBasic讨论:37677395
ESBasic开源前言

ESBasic 可复用的.NET类库(06) -- 循环任务切换器 CircleTaskSwitcher


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论