Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 13 total
Thread UI Feedback from a code loop
Thu, Feb 21 2019 3:13 PMPermanent Link

Michael Saunders

I  store  multiple transactions on a mobile device when it is out of wi fi range and then when eventually in range press a button which loops through these and updates an EDB server database table

As this takes time I would like to present UI feedback as to  progress of the updates  However due to the asynchronous nature of EWB I am having trouble in doing this as I would like

The following code works fine

begin
 ShowProgress('Posting Pattern Changes');
 async PostPatterns;
end;

where the code  in PostPatterns loops through the transactions, finds the record to be changed and Commits a Database transaction

eg
   while not tbChangedPatterns.eof do
      begin
         // Here I find, update and commit the record to be changed
         tbChangedPatterns.next;
      end;

Ideally I would like to display a running count as each record is  posted as there could be quite a few of them  Alternatively a Progress Bar to give some indication of progress would suffice but  I am struggling to do this

Is this possible with the single threaded nature of EWB and JS being what it is An example of how to so this would be appreciated

Thanks
Fri, Feb 22 2019 3:12 AMPermanent Link

Walter Matte

Tactical Business Corporation


I do this type of UI Feedback.

in my particular case I have a Dataset I am looping through.

In a button On Click I start the Process:


Begin
   TSAdmin.First;    //   This is the Dataset

   If TSAdmin.EOF then EXIT;

    //
    // Update Screen to visually show using things are moving!!
   //
   lbName.Caption := 'Calc: ' + TSAdmin.Columns['CandName'].AsString;
   lbName.Visible := true;

   // Send Id  Number to server to do work for 1 person
   srFunc.URL := gbURL + '/qfunc';
   srFunc.Params.Clear;
   srFunc.Params.add('FUNC=CALCUPDSICKVAC');
   srFunc.Params.add('ITMEID=' + TSAdmin.Columns['TimeId'].AsString);
   srFunc.execute;
End;

In the On Function  Complete - I cannot call the function within the function to I turn on a timer

Begin
 if (Request.StatusCode=200) then
 begin
       tiCalcUpdSickVac.Enabled := true;   // 300 ms  could be 100...
 end
 else
   // Error Code
end;


The OnTimer Event  - gets next record - updates UI or if no record stops updates control info that task is done.

procedure TfrmSelTimeAdmin.tiCalcUpdSickVacTimer(Sender: TObject);
begin

 tiCalcUpdSickVac.Enabled := false;

 tsAdmin.Next;     // Get Next Record
 While not TSAdmin.EOF do
 begin
   if (TSAdmin.Columns['TimeId'].Null) then
   begin
      tsAdmin.Next;
   end
   else
   begin
     lbName.Caption := 'Calc: ' + TSAdmin.Columns['CandName'].AsString;
     lbName.Visible := true;
     srFunc.Tag := 3;
     srFunc.URL := gbURL + '/qfunc';
     srFunc.Params.Clear;
     srFunc.Params.add('FUNC=CALCUPDSICKVAC');
     srFunc.Params.add('UBCTIMEID=' + TSAdmin.Columns['TimeId'].AsString);
     srFunc.execute;
     exit;
   end;
 end;    
                    
 Control.Update;
 Control.Columns['AccumDate'].asDateTime := FToDT;
 Control.Save;


 lbName.Visible := false;
 RunningProc := 0;
 ShowMessage('Calculation Completed.');
end;



 Walter
Fri, Feb 22 2019 3:48 AMPermanent Link

Matthew Jones

Michael Saunders wrote:

>     while not tbChangedPatterns.eof do

I agree with Walter - and the key is that no UI will update until your code "stops". What I did in one application was to have a list of items to process. I'd then have a current item, and would do a loop of so many items, and then stop and have a timer or other external trigger (like a web http result) set it off again from where it left off.

--

Matthew Jones
Fri, Feb 22 2019 10:12 AMPermanent Link

Uli Becker

Michael,
 
> Is this possible with the single threaded nature of EWB and JS being what it is An example of how to so this would be appreciated

Here what I do to show a progress of batch operations:

I execute the code in a module. After each "action" the module writes something in a progress table.
In EWB I poll this table using a timer (the interval is up to you) and have a reliable progress information without writing much code.

Uli


Fri, Feb 22 2019 11:13 AMPermanent Link

Walter Matte

Tactical Business Corporation

Thanks Uli... I like that...
Fri, Feb 22 2019 4:22 PMPermanent Link

Michael Saunders

Thanks for the replies  So can I take it that the only way to achieve what i need to do is to make use of a server module and timer and explore how these can work with each other

Thanks
Fri, Feb 22 2019 4:28 PMPermanent Link

Raul

Team Elevate Team Elevate

On 2/22/2019 4:22 PM, Michael Saunders wrote:
> Thanks for the replies  So can I take it that the only way to achieve what i need to do is to make use of a server module and timer and explore how these can work with each other

There should be no need for server module.

You core issue is with you running a tight loop (while) which would
prevent UI updates.

Idea is to use timer to essentially single step this - each step updates
progress UI and then moves the dataset record and commits.

This allows progress to be seen basically.

Raul
Mon, Feb 25 2019 5:36 AMPermanent Link

Michael Saunders

In trying to understand async programming and resolve my issue I have put together a very simple demo

procedure TfmSummary.Button1Click(Sender: TObject);
begin
 count := 0;
 timer1.enabled:= true;
end;

procedure TfmSummary.Timer1Timer(Sender: TObject);
begin
 lbmessage.caption := inttostr(count);
 if count = 10 then
    exit;
 inc(count);
end;

The above appears to work as expected but if I move  
inc(count)  
higher up the coding, the loop appears to continue indefinitely

Furthermore if I put
timer.enabled := false
at the start of the loop the timer is not disabled and still continues as before

Why is this please
Mon, Feb 25 2019 5:47 AMPermanent Link

Walter Matte

Tactical Business Corporation

It you stop the timer in the timer event - then you have stop the process completely.  You have told the "looping" to stop. (and have never told it to restart somewhere else).


In the case where you move the inc(count) - you never stopped the timer so it continues forever.


I my example (earlier in this thread) I stop the timer while executing a ServerRequest - and I restart the timer when the response comes back to the Browser from the server - and then continue the loop.  You have the Browser and the Server and when you ask the Server to do something you do not know how long it will take so you have to wait for an event like ServerResponse to know the work is done or not possibly. (error conditions).


You are missing the trip to server and back - which is what happens when you update you dataset or whatever else you are trying to accomplish.
Mon, Feb 25 2019 11:41 AMPermanent Link

Michael Saunders

Walter Matte wrote:

It you stop the timer in the timer event - then you have stop the process completely.  You have told the "looping" to stop. (and have never told it to restart somewhere else).

On checking my code I realised that  I was inadvertently referencing a different timer so yes works as I thought it should

In the case where you move the inc(count) - you never stopped the timer so it continues forever.

For some strange reason I had got it into my head that exit stoppped the timer Very embarrasing

I my example (earlier in this thread) I stop the timer while executing a ServerRequest - and I restart the timer when the response comes back to the Browser from the server - and then continue the loop.  You have the Browser and the Server and when you ask the Server to do something you do not know how long it will take so you have to wait for an event like ServerResponse to know the work is done or not possibly. (error conditions).

You are missing the trip to server and back - which is what happens when you update you dataset or whatever else you are trying to accomplish.

Indeed I understood this from your example and that is why I thought I needed a Server Module to provide this However as I understood from Raul's respone to this question he seemed to indicate that this was not necessary So are you saying I do need a server module
Page 1 of 2Next Page »
Jump to Page:  1 2
Image