• 解决kbmMW Scheduler在任务中停止任务遇到的问题


    kbmMW提供了强大的Scheduler Framework,用来做调度任务的算法,在我看来,Scheduler发展了几个版本之后,截至到目前为止,更象是一个多线程框架,用来开发多线程算法。关于如何应用Scheduler,我翻译了作者写过的所有文章,可以去查看。今天要写的是实际项目中遇到的一个问题,如何用Scheduler来解决以及在解决过程中遇到的问题。

    先看下需求:

    有一个定位任务,在定位时,我显示一个等待界面,如果定位超时,则隐藏这个等待界面。下面是写的第一个版本的代码,建立一个每秒执行一次的调度任务,如果超时,则隐藏等待定位结果的界面,并停止调度任务。这里让调度任务与主线程同步执行:

    procedure TCustomGridViewCameraDoc.InitSchedule;
    begin
      Scheduler.Schedule(
        procedure(const AScheduledEvent:IkbmMWScheduledEvent)
        begin
                  //隐藏等待定位界面
            ... AScheduledEvent.Terminate;
    //停止任务(必须 .SyncQueued) end).EverySecond(1).Synchronized.NamedAs('se_job1') end;

    上面的代码出问题了,当调用AScheduledEvent.Terminate,应用卡死

    换一种写法,测试正常:

    procedure TCustomGridViewCameraDoc.InitSchedule;
    begin
      se_job1 := Scheduler.Schedule(
        procedure(const AScheduledEvent:IkbmMWScheduledEvent)
        begin
                ... 
                AScheduledEvent.Terminate;//正常!
        end).EverySecond(1)
            .SyncQueued//Synchronized换成SyncQueued
            .NamedAs('se_job1')
    end;

    或者这样写,也正常:

    procedure TCustomGridViewCameraDoc.InitSchedule;
    begin
      se_job1 := Scheduler.Schedule(
        procedure(const AScheduledEvent:IkbmMWScheduledEvent)
        begin
                  TThread.Synchronize(nil,procedure
                  begin
                          ....;
                  end);//这样同步主线程执行逻辑
                AScheduledEvent.Terminate;
        end).EverySecond(1).NamedAs('se_job1')
    end;

    算不算是bug呢?我也说不清了。

    进一步测试,又发现问题,当用下面代码重新激活这个调度事件(ScheduledEvent)发现无法激活,即调度任务不执行了。

    Scheduler.Events.GetByName('se_job1').Activate;

    通过把AScheduledEvent.Terminate替换成AScheduledEvent.Activate(False),问题得到解决。通过这个问题可以得出结论:当调用Terminate方法后,这个事件将无法重新Activate

    下面是最后的版本

    procedure TCustomGridViewCameraDoc.InitSchedule;
    begin
      //避免重复建立调度事件
      if Scheduler.Events.GetByName('se_job1') <> nil  then exit;
      //建立一个调度事件,命名为se_job1
      Scheduler.Schedule(
                          procedure(const AScheduledEvent:IkbmMWScheduledEvent)
                          begin
                                  AScheduledEvent.Activate(False);//必须 .SyncQueued
                          end)
               .EverySecond(1)
               .SyncQueued
               .NamedAs('se_job1')
    end;
  • 相关阅读:
    001-nginx基础配置-location、Rewrite、return 直接返回码、全局变量
    001-Spring Cloud Edgware.SR3 升级最新 Finchley.SR1,spring boot 1.5.9.RELEASE 升级2.0.4.RELEASE注意问题点
    004-读书记录
    007-ant design 对象属性赋值,双向绑定
    006-ant design -结合echart-地址map市
    005-ant design -结合echart
    002-Spring Framework-Core-01-IoC容器
    003-驾照考试,总结
    006-markdown基础语法
    java-mybaits-010-mybatis-spring-使用 SqlSession、注入映射器
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/12372855.html
Copyright © 2020-2023  润新知