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;
  • 相关阅读:
    无限维
    黎曼流形
    why we need virtual key word
    TOJ 4119 Split Equally
    TOJ 4003 Next Permutation
    TOJ 4002 Palindrome Generator
    TOJ 2749 Absent Substrings
    TOJ 2641 Gene
    TOJ 2861 Octal Fractions
    TOJ 4394 Rebuild Road
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/12372855.html
Copyright © 2011-2022 走看看