zoukankan      html  css  js  c++  java
  • 在指定时间干,必须干(kbmmw 中的事件调度)

        从去年开始,kbmmw 慢慢增加内涵,除了完善各种服务外,陆续增加和扩展了作为一个中间件必须有的功能,

    例如,权限管理、日志系统、调度系统、内存调试等功能。

        今天给大家介绍一下kbmmw 的调度事件,调度事件的主要目标就是”在指定时间干,必须干“,不是“爱干”不干,是“必须干” :)。

    在传统的delphi 中事件调度室通过两种方式,一种方式通过Ttimer 来实现,(我20年做的母校的食堂餐饮消费系统就是通过Ttimer来轮询

    POS 机的)。另外一种就是通过扩展Tthread 线程类,通过后台完成一些指定事件。

       利用Ttimer 来完成事件调度,其实是一个松散的调度,其依靠windows 的消息机制,如果一个事件在指定事件没有做完,

    那么后面的消息就会被忽略,这样会丢失一些事件,在很多场合是不允许的。

      利用扩展线程实现调度,可以比较精确的执行调度事件,但是由于多线程编写程序复杂,而且精确时间的计算也要一定的

    功力及技巧,一般开发者往往望而却步。

        那么怎么办呢? kbmmw 来帮忙,在新版的kbmmw 中,加入了TkbmMWSchedule 类,这个类用来完成事件调度,完成

    ”在指定时间干,必须干“这个任务。这个类简单易用,不但简单易用,而且包括了很多调度启动、关闭的相关操作。

       TkbmMWScheduler 类不但是一个任意数量调度事件的容器,也是一个调度事件的管理器。确保这些事件在正确的事件被执行。

    Kbmmw 自带一个标准的TkbmMWScheduler 类,名称就叫kbmMWScheduler,这个是kbmmw 自用的,你同样可以用它,当然

    了,你也可以任性自己再建一个自己独立的。

          ok. 让我们先简单的看一下一个例子。

           kbmMWScheduler.Schedule(OnScheduledEvent).EverySecond(10).Activate(true);

    以上的代码就是让调度器每10秒做一件事情。在调度事件里面我们可以写一下代码。

      function TForm1.OnScheduledEvent(const AScheduledEvent:IkbmMWScheduledEvent):boolean;

      begin

             call('无为,干活');

             result:=True; 

      end;

    这样这个事件就一直被执行下去,无为估计就会疯了:)

    为了不让无为发疯,我们需要可以停止这个事件。那么为了能够停止这个事件,我们需要先给这个调度定义,以

    方便我们后面停止这个调度操作。

    以下代码来控制这个调度

    var

       myevent:IkbmMWScheduledEvent;

      myevent:=kbmMWScheduler.Schedule(OnScheduledEvent).EverySecond(10).Activate(true);

    好了,我们知道是哪个事件了,后面就好办了。

        myevent.Active:=false;

    这样,无为就消停了(无为到底是什么鬼?)。

    当然了,我们也可以通过强行命名一个调度器,以便后面方便操作。

    kbmMWScheduler.Schedule(OnScheduledEvent).NamedAs(‘xalion’).EverySecond(10).Activate(true);

    这样,后面可以通过名称查找这个调度,然后操作这个调度

    xalionev:=kbmMWScheduler.GetByName(‘xalion’);

    kbmmw 中的时间调度有两种,一种是松散调度,一种是精确调度。

    松散调度是通过一个线程池来完成的,所有的调度时间共享一个线程池,它保证事件的运行,但是不保证精确度。由于是共享线程池,

    因此松散调度调度节省系统资源,这种调度适合于数据备份等场合,例如确保每天晚上12点左右备份数据,但是没有必要在12:00:00

    那一瞬间执行这个事件,kbmmw 中默认调度为松散调度。但是某些场合,我们必须在精确的指定时间执行一个事件,例如上、下课铃声,我们谁也不愿意

    下课时间到了,还没听见下课铃声。这个就需要精确事件调度,为了适合满足这种要求,kbmmw 为其单独建立一个线程,确保

    这个事件精确按时执行,代价是会增加系统资源的使用(当然了也有例外,如果系统本身很忙,例如CPU 负载100%,神仙也没办法了)。

    建立精确事件调度在kbmmw 里面也很简单,代码如下,

    kbmMWScheduler.Schedule(OnScheduledEvent).NamedAs(‘xalion’).EverySecond(10).Precise.Activate(true);

    当然了,你也可以用下面代码定义松散调度。

    kbmMWScheduler.Schedule(OnScheduledEvent).NamedAs(‘xalion’).EverySecond(10).Relaxed.Activate(true);

    kbmmw 不但支持秒为执行间隔,还有很多间隔方法。

    EveryMSecond(n)  ---每n毫秒,什么东西要这么快?

    EveryMinute(n) -------每n分钟,测量心跳?

    EveryHour(n)---------每n小时,当n=1 时,8次就可以下班了?不可能

    EveryDay(n) -----------每n天,当n=1 时,就是程序猿的闹钟

    EveryMonth(n) ----------每n月一次,当n=1 时,是什么?

    EveryYear(n) --------------你开发的系统,能n年不重新启动?

       其实这个n 可以是小数, EveryDay(0.5) 就是半天。

    注意,很人性化的一点出现了

    EveryDay(1).EveryHour(6)  是多少呢? 呵呵,其实就是EveryHour(30),24+6=30 小时。

    那么 EveryMonth(2.5).EveryHour(3) 是多少呢? 2.5 个月到底是多长时间?自己调试吧。

    每个星期几必须要做,怎么办?

    AtWeekDays([mwwdSunday,mwwdWednesday])

    在指定的日期范围内执行也很简单

    .StartingAt(TkbmMWDateTime.Create(‘2015-11-22T15:00:00GMT’)).
    .EndingAt(TkbmMWDateTime.Create(‘2015-12-22T15:00:00GMT’)).
     
    如果你想在执行前等一会儿,也没问题
    DelayInitial(TkbmMWDuration.Create(10)).
     
    你也可以只让这个调度事件只做一次
    .Occurs(mwsoOnce).
     
     
     
    当然了,你也可以通过写匿名函数来替换调度事件
    FScheduler.Schedule(
    function(const AScheduledEvent:IkbmMWScheduledEvent):boolean
    begin
    mData.Lines.Add('anonymous:'+AScheduledEvent.Name);
    Result:=true;
    End
    ).NamedAs('Relaxed event Every 2 secs').EverySecond(2).Synchronized.Activate(true);
     
    不知道kbmmw这样的调度,是否能满足你的需要?如果不满足,那你就自己写吧,反正我不会写。
     
     
  • 相关阅读:
    BigDecimal工具类处理精度计算
    Redis的简单使用和介绍
    数据库优化知识总结
    js弹出QQ对话框在线交谈
    火焰灯menu修改之后,可以实现数遍点击小方块停留在当前页面
    js作用域的一个小例子
    js中this的四种调用模式
    jquery火焰等效果导航菜单
    appserver配置虚拟主机
    一个类似百度文库选中弹出个小框的效果
  • 原文地址:https://www.cnblogs.com/xalion/p/5544046.html
Copyright © 2011-2022 走看看