zoukankan      html  css  js  c++  java
  • 解决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;
  • 相关阅读:
    数据库维护单数据修改(入库单月份更改)
    Git下载GitHub上的文件
    水晶报表的步骤
    html表格及列表
    html中的a标签
    了解html标签
    常见编码方式(码表)
    了解html
    Odoo官方翻译网站
    postgresql性能的几个重要参数
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/12372855.html
Copyright © 2011-2022 走看看