ONLINE HELP
 WINDEVWEBDEV AND WINDEV MOBILE

Help / Developing an application or website / Controls, windows and pages / Page / Programming
  • Overview
  • Principle
  • Implementation
  • Example
  • Parallel tasks for run the long process
  • Calling RequestRefreshUI
  • "Request for refreshing the display" event
  • Browser timer
  • Disabling the timer
  • Alternative approach
WINDEV
WindowsLinuxUniversal Windows 10 AppJavaReports and QueriesUser code (UMC)
WEBDEV
WindowsLinuxPHPWEBDEV - Browser code
WINDEV Mobile
AndroidAndroid Widget iPhone/iPadIOS WidgetApple WatchMac CatalystUniversal Windows 10 App
Others
Stored procedures
Page in Session mode: Populating controls after a long process
Overview
In a web application, you may need to run long processes (for example, to update counters in a dashboard). This page explains how to run these processes:
  • without blocking the user interface,
  • by automatically updating the data displayed when new values are available.
Principle
To populate controls with the results of long processes without blocking the browser, there's a reliable and relatively simple solution:
  1. Use secure threads or parallel tasks to prepare the results in global variables,
  2. Call the WLanguage RequestRefreshUI function from the threads or parallel tasks when the results are available,
  3. Write the code to update the controls in the "Request for refreshing the display" event,
  4. Set up a browser timer that calls an asynchronous AJAX server procedure to update the controls and refresh the UI every 10 seconds or every minute, for example,
  5. Enable/Disable the timer as needed to avoid unnecessary AJAX calls.
Implementation

Example

Let's use the following example to go through the different steps:
  • a page containing an Dashboard control
  • the new counter values are calculated in a local procedure named UpdateKIP.
  • the code that starts dashboard update is written in the "Update (asynchronous)" Button control.

Parallel tasks for run the long process

In the server code of the Button control, the execution of the UpdateKIP procedure is launched in a parallel task. This means that the UI is not blocked and remains responsive.. For example:
gUpdateParallelTask is ParallelTask
gUpdateParallelTask  = ParallelTaskExecute(UpdateKIP, ())
In this code, a reference to the parallel task is stored in the gUpdateParallelTask global variable.
To avoid launching several recalculation tasks at the same time, the Button control code checks the State property of the ParallelTask variable.
IF gUpdateParallelTask.State = ptsExecutionInProgress
ToastDisplay("Request already in progress", toastShort, vaTop, haCenter, PastelGreen)
ELSE
gUpdateParallelTask  = ParallelTaskExecute(UpdateKIP, ())
END
In the browser code of the Button control, a timer is also started every second to execute a browser procedure (let's call it Update_Browser).
gnUpdateTimer = Timer(Update_Browser, 1 s)
Remark: In this example, the timer procedure is called every second. It may not be necessary to execute the timer procedure so often. Feel free to adjust the update frequency.

Calling RequestRefreshUI

The code of the UpdateKIP procedure recalculates the counters in the dashboard. When the server variables that are global to the page are up to date, the UpdateKIP procedure calls RequestRefreshUI.
This function enables WLanguage to execute the "Request for refreshing the display" event as soon as possible.
The procedure ends, terminating the parallel task.
The State property of the parallel task is then set to ptsCompleted.

"Request for refreshing the display" event

The "Request for refreshing the display" event contains the code that updates the controls.
In our example:
LOOP_KIP[gnDailyTurnoverRow].ATT_KIPName = StringBuild(gsDailyTurnover, gnDailyTurnover)
LOOP_KIP[gnNumberOrdersRow].ATT_KIPName = StringBuild(gsNumberOrders, gnOrders)

Browser timer

During this time, the browser timer (Update_Browser procedure in our example) regularly executes the Update_Server server procedure.
This procedure is executed via an asynchronous AJAX call. Again, the purpose is to avoid blocking the UI.
AJAXExecuteAsynchronous is called by specifying the ajaxUpdateControls constant.
AJAXExecuteAsynchronous(ajaxUpdateControls + ajaxSynchronizeServerVariables, ...
Update_Server, AfterUpdate_Browser)
This constant allows the server code to update the controls in the page. The server call will automatically update the UI. The Update_Server procedure returns only the value of gUpdateParallelTask.State.
AJAXExecuteAsynchronous automatically calls a browser procedure when the server response is received. In the example, it is the AfterUpdate_Browser procedure.

Disabling the timer

The AfterUpdate_Browser takes the following parameters:
  • the value returned by the server procedure, here gUpdateParalleTask.State. Thus, if the parallel task is completed ( ptsCompleted constant), the timer is stopped to prevent unnecessary server calls.
  • an identifier for the relevant server procedure. This identifier can be very helpful if there are multiple simultaneous AJAX calls.
PROCÉDURE AfterUpdate_Browser(sTaskStatus is string, nIdentifier is int)

Alternative approach

If the process takes a long time and requires a significant amount of resources on the server side, it may be worthwhile to move the process somewhere else.
In that case, simply use a WEBDEV scheduled task to perform the long process at regular intervals and store the results in the database. The site will just have to display the stored results.
See also
Minimum version required
  • Version 28
Comments
Click [Add] to post a comment

Last update: 09/11/2023

Send a report | Local help