Batching Operations
Batching is a way of collecting multiple file operations in one request to the locally installed file service. Each request requires a round trip to the local service. If you have many file operations, the performance will suffer if you use a round trip for every operation.
To overcome this problem in the architecture of web-based file operations, we have included the possibility of batch file operations. This feature lets you bundle multiple file operations in one request to the local file service.
Create a task
The way this works is that you create a list of tasks. Each task is a file operation. Instead of calling a function that does the operation immediately, you make a task that will be carried out when all the tasks are sent to the local file service in one request.
Let's illustrate it with an example where a file is written. You would typically write AL code similar to this:
FileService.WriteText('DEMOFILES:\test1.txt', 'Hello world!');
FileService.WriteText('DEMOFILES:\test2.txt', 'Hello again!');
This will write the text files one at a time, and the code execution will wait for each file to be written. Instead, you can call this:
FileService.WriteTextTask('DEMOFILES:\test1.txt', 'Hello world!');
FileService.WriteTextTask('DEMOFILES:\test2.txt', 'Hello again!');
FileService.RunTasks();
Here, the two write operations are sent to the local file service as one request. Therefore, the entire operation is approximately twice as fast.
Read the result
Every operation that creates a task also returns a task identifier. The identifier is an integer number that helps you get the operation's result. In the write example above, the result is only needed if you want to check for errors. Otherwise, it is not required.
Read file operations are different. Here, we want to get the result, which is the content of the files. Therefore, we save the identifiers of the tasks we create.
id1 := FileService.ReadTextTask('DEMOFILES:\test1.txt');
id2 := FileService.ReadTextTask('DEMOFILES:\test1.txt');
FileService.RunTasks();
FileService.GetReadTextTaskResult(id1, text1);
FileService.GetReadTextTaskResult(id2, text2);
Message('File 1:\%1\\File 2:\%2', text1, text2);
For each function that creates a task, there is an equivalent function that gets the result. These functions take the task identifier as a parameter and a variable for the result.
Error handling
There is a simple way to check if individual tasks have failed. The function that gets the results returns a boolean that indicates whether the operation was a success or not. If an error occurs, you can get the error message using the GetTaskError
function.
FileService.SetErrorAction("ForNAV File Error Action"::Ignore);
id1 := FileService.ReadTextTask('DEMOFILES:\test1.txt');
id2 := FileService.ReadTextTask('DEMOFILES:\test1.txt');
FileService.RunTasks();
if not FileService.GetReadTextTaskResult(id1, text1) then
Message(FileService.GetTaskError(id1));
if not FileService.GetReadTextTaskResult(id2, text2) then
Message(FileService.GetTaskError(id2));
if FileService.LastError() = '' then
Message('File 1:\%1\\File 2:\%2', text1, text2);
As shown in the code above, you can set the error action to ignore errors. This will continue to execute the batched tasks even if one of them fails.
Limitations
Depending on the content of your operations, the size of the request or response may exceed the capacity of your installation. If you encounter such limitations, consider breaking up your batches into smaller ones.