How-To use Page Background Tasks in Business Central

The other day I had a task where I had to do quite an elaborate calculation to be displayed on a Business Central page. Finally I was able to use the new page background task functionality.

The idea behind these page background tasks ist as genius as it is simple. Let’s load intensive data in the background to not block the UI and keep it responsive. To achieve this, a background session could be started using CurrPage.EnqueueBackgroundTask which returns a unique Task-ID. The moment this background task is executed successfully, it raises an event OnPageBackgroundTaskCompleted, on which we check the responded Task ID against. If the Task ID of the response event matches our saved Task ID we can process the data as it is the result we’re listening to.

Important: Page background sessions must not change data! They are read-only!

Background Task Flow

A background task is a multithread operation between the parent and child sessions. The following diagram illustrates the flow of a background task. In the illustration, the threads start in the order: THREAD A, THREAD B, THREAD C.

Source: Microsoft

Page Background Tasks

Example

This example has no specific task. Its intention is to show the pattern only.

Initiate

We start the pbt defining the codeunit and some additional parameters.

//Create a global var to save our started Task ID
var
    WaitTaskId: Integer;

//Then trigger the background task
trigger OnAfterGetRecord()
var
    TaskParameters: Dictionary of [Text, Text];
begin
    // Add as many key-value pairs to the dictionary as you want
    TaskParameters.Add('MyPrimaryKey1', Rec."Primary Key Field 1");
    TaskParameters.Add('MyPrimaryKey2', Rec."Primary Key Field 2");

    //Enqueues the page background task and save the Task ID in our global WaitTaskId var
    CurrPage.EnqueueBackgroundTask(WaitTaskId, Codeunit::"Page Background Runner", TaskParameters);
end;

Process

Now the background session will be executed while the UI stays fully responsible. The background task itself must be a codeunit that could be parametrized however you want through the dictionary as seen above.

Important: Background sessions are automatically closed when the record is changed!

//Our Page Background Tasks codeunit
trigger OnRun()
var
    Result: Dictionary of [Text, Text];
begin
    //This might be a check of the params
    if not Evaluate(ContainerName, Page.GetBackgroundParameters().Get('MyPrimaryKey1')) then
        Error('Mandatory parameter not found');

    if not Evaluate(FileIdentifier, Page.GetBackgroundParameters().Get('MyPrimaryKey2')) then
        Error('Mandatory parameter not found');

    //Do something with your record, call a webservice or whatever
    //...

    //Write back whatever data you like
    Result.Add('ProcessingDone', 'true');

    //Send back to the OnPageBackgroundTaskCompleted event 
    Page.SetBackgroundTaskResult(Result);
end;

Result

Now that the response event is activated we can process the response.

//Here comes our response
trigger OnPageBackgroundTaskCompleted(TaskId: Integer; Results: Dictionary of [Text, Text])
var
    IsUpdated: Boolean;
begin
    //Am i the task-id my ui is waiting for?
    if (TaskId = WaitTaskId) then 
        if Results.ContainsKey('ProcessingDone') then
            if Evaluate(IsUpdated, Results.Get('ProcessingDone')) then begin
                //do whatever you like
            end,    
end;

//Sure, there might also be some errors
trigger OnPageBackgroundTaskError(TaskId: Integer; ErrorCode: Text; ErrorText: Text; ErrorCallStack: Text; var IsHandled: Boolean)
begin
    //Do something. f.ex. show a notification
    //...
end;

For sure you could also stop the background session if you want using Page.CancelBackgroundTask(TaskId: Integer).

Conclusion

I think page backgound tasks are an important step in the right direction to bring the webclient forward and differentiate it from the fullclient. In particular long loading data, webservices or the additional use of background tasks bring new possibilities to build rich interfaces… not at the expense of performance!

... is a technical consultant and developer at Comsol Unternehmenslösungen AG in Kronberg/Taunus. Major tasks are the architecture and implementation of complex, usually cross-system applications in and around Microsoft Dynamics 365 Business Central.

Leave a Reply

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