Next release of kbmMW further improves on the TkbmMWScheduler. The scheduler supports adding jobs to run given a quite extensive set of time conditions. It also already supports running jobs in the background, and when they are done, handle some foreground update of the GUI in a safe and consistent way.

However what if you want to run a number of jobs in parallel in the background and only call the job a success when all the background sub jobs has finished.

kbmMW will allow you to do that in a simple way in next release. Here is some example code.

procedure TForm1.Button10Click(Sender: TObject);
var
  d1:int64;
begin
  d1:=TkbmMWTiming.GetTimeUS;
  Scheduler.Run([
   procedure(const AScheduledEvent:IkbmMWScheduledEvent)
   var
      i,n:integer;
      d:int64;
   begin
        AScheduledEvent.Data:=0;
        n:=500;
        d:=TkbmMWTiming.GetTimeUS;
        for i:=0 to n-1 do
        begin
             if AScheduledEvent.Terminating then
                break;
             sleep(10);
        end;
        d:=TkbmMWTiming.Diff(d);
        AScheduledEvent.Data:=d;
   end,
   procedure(const AScheduledEvent:IkbmMWScheduledEvent)
   var
      i,n:integer;
      d:int64;
   begin
        AScheduledEvent.Data:=0;
        n:=400;
        d:=TkbmMWTiming.GetTimeUS;
        for i:=0 to n-1 do
        begin
             if AScheduledEvent.Terminating then
                break;
             sleep(10);
        end;
        d:=TkbmMWTiming.Diff(d);
        AScheduledEvent.Data:=d;
   end]
  )
  .NamedAs('MultipleWithSync')
  .SynchronizedAfterRun(
   procedure(const AScheduledEvent:IkbmMWScheduledEvent)
   begin
        mData.Lines.Add('Run multiple with sync - anonym (uS):'+VarToStr(AScheduledEvent.ChildEvent[0].Data)+','+VarToStr(AScheduledEvent.ChildEvent[1].Data));
        mData.Lines.Add(' Total passed time (uS):'+IntToStr(TkbmMWTiming.Diff(d1)));
   end)
  .Activate;
end;

One interesting part is the Run method, which now takes an array of procedures or functions to run. What happens internally, is that a scheduled event is defined, which in turn defines a number of child scheduled events that each process the given jobs.

Only when all jobs are done, the AfterRun method is executed.

Another interesting thing to notice, is that the AfterRun method can tap into data provided by any of the child events. In this case the child events time how long time they ran. The AfterRun method displays that, along with the total run time.

In this case, the total time is only slightly longer than the time for the longest running job because the jobs ran in parallel.

A few more fluent methods has also been added:

WithObject(AObject:TObject) and WithInterface(AInterface:IInterface) which allows you to tag on an object or an interface to an event. It could be used to provide data for the job, or to receive data from the job.

Only remember, that jobs are run multithreaded. Thus your object or interface must be threadaware.

Finally this example shows how a long running job should check for termination. Termination happens when the Terminate method is called on the running scheduled event, or when the scheduler is closing down, for example due to the application being shutdown.

That’s all for now.

Loading

2 thoughts on “kbmMW Scheduler Tidbits #5 -Synchronize multiple parallel jobs”
    1. Hi,
      Basically:

      Scheduler.Run(
      procedure (const AEvent:IkbmMWScheduledEvent)
      begin
      …:=AEvent.&Object.Someproperty; // But accessing Someproperty must be threadsafe.
      end).WithObject(yourobject).Activate;

      best regards
      Kim/C4D

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.