DEV Community

SameX
SameX

Posted on

The World of HarmonyOS Programming: In - depth Understanding of Concurrent Task Execution of TaskPool and Worker

This article aims to deeply explore the technical details of the Huawei HarmonyOS Next system (up to API 12 as of now), and is summarized based on actual development practices. It mainly serves as a vehicle for technical sharing and communication. Mistakes and omissions are inevitable. Colleagues are welcome to put forward valuable opinions and questions so that we can make progress together. This article is original content, and any form of reprint must indicate the source and the original author.
The HarmonyOS system provides two concurrent capabilities: TaskPool and Worker. Both of them are implemented based on the Actor concurrent model, but their usage scenarios and functions are different.

  • TaskPool: TaskPool is a multi - threaded running environment that provides functions such as task execution, cancellation, and priority setting. TaskPool is suitable for independent tasks, such as computationally - intensive tasks and I/O - intensive tasks.
  • Worker: Worker is a long - running background thread that supports message passing between the hosting main thread. Worker is suitable for long - running tasks, such as background data processing and model training. ### Differences and Usage Scenarios of TaskPool and Worker | Feature | TaskPool | Worker | |---|---|---| | Memory Model | Threads are isolated, and memory is not shared. | Threads are isolated, and memory is not shared. | | Parameter Passing Mechanism | Use the standard Structured Clone algorithm for serialization and deserialization to complete parameter passing. Support the transfer of ArrayBuffer and the sharing of SharedArrayBuffer. | Use the standard Structured Clone algorithm for serialization and deserialization to complete parameter passing. Support the transfer of ArrayBuffer and the sharing of SharedArrayBuffer. | | Parameter Passing | Pass directly without encapsulation, and transfer is performed by default. | The message object is the only parameter and needs to be encapsulated by yourself. | | Method Invocation | Pass the method directly for invocation. | Parse the message in the Worker thread and invoke the corresponding method. | | Return Value | Returned by default after asynchronous invocation. | Send a message actively, and need to be parsed and assigned in onmessage. | | Lifecycle | TaskPool automatically manages the lifecycle, and there is no need to worry about the high or low task load. | Developers manage the number and lifecycle of Workers by themselves. | | Upper Limit of the Number of Task Pools | Automatically managed without configuration. | In the same process, a maximum of 64 Worker threads can be opened simultaneously. The actual number is determined by the process memory. | | Upper Limit of Task Execution Duration | 3 minutes (excluding the time - consuming asynchronous calls of Promise and async/await, such as the time - consuming of I/O tasks such as network download and file read - write). There is no upper limit for long - term tasks. | No limit. | | Setting Task Priority | Support configuring task priority. | Not supported. | | Canceling Task Execution | Support canceling the initiated task. | Not supported. | | Thread Reuse | Support. | Not supported. | | Task Delay Execution | Support. | Not supported. | | Setting Task Dependency Relationship | Support. | Not supported. | | Serial Queue | Support. | Not supported. | | Task Group | Support. | Not supported. | Usage Scenarios:
  • TaskPool: Suitable for independent tasks, such as computationally - intensive tasks and I/O - intensive tasks.
  • Worker: Suitable for long - running tasks, such as background data processing and model training. ### Management of TaskGroup and Task Priority TaskGroup: TaskGroup is a set of tasks. Multiple tasks can be added to the TaskGroup and executed together. TaskGroup supports configuring the priority of tasks. Example:
import { taskpool } from '@kit.ArkTS';
@Concurrent
function add(num1: number, num2: number): number {
    return num1 + num2;
}
@Concurrent
function subtract(num1: number, num2: number): number {
    return num1 - num2;
}
async function concurrentFunc() {
    const task1 = new taskpool.Task(add, 1, 2);
    const task2 = new taskpool.Task(subtract, 3, 4);
    const group = new taskpool.TaskGroup();
    group.addTask(task1);
    group.addTask(task2);
    group.addTask(task1); // Add a duplicate task
    await taskpool.execute(group, taskpool.Priority.HIGH);
}
Enter fullscreen mode Exit fullscreen mode

Task Priority:

  • Priority.IDLE: Background task with the lowest priority.
  • Priority.LOW: Low - priority task.
  • Priority.MEDIUM: Medium - priority task.
  • Priority.HIGH: High - priority task. ### Task Addition and Execution Logic Task Addition:
const task = new taskpool.Task(func, args);
Enter fullscreen mode Exit fullscreen mode

Task Execution:

await taskpool.execute(task);
Enter fullscreen mode Exit fullscreen mode

Task Cancellation:

taskpool.cancel(task);
Enter fullscreen mode Exit fullscreen mode

Example Code: An Example of Executing CPU - Intensive Tasks through TaskPool

The following is a simple example demonstrating how to use TaskPool to execute CPU - intensive tasks:

import { taskpool } from '@kit.ArkTS';
@Concurrent
function complexCalculation(data: ArrayBuffer): ArrayBuffer {
    // Perform complex calculation operations
    return data;
}
async function concurrentCalculation() {
    const data = new ArrayBuffer(1024);
    const task = new taskpool.Task(complexCalculation, data);
    await taskpool.execute(task);
}
@Entry
@Component
struct Index {
    @State message: string = 'Hello World';
    build() {
        Row() {
            Column() {
                Text(this.message)
                  .fontSize(50)
                  .fontWeight(FontWeight.Bold)
                  .onClick(async () => {
                        await concurrentCalculation();
                    })
                  .width('100%');
            }
        }
      .height('100%');
    }
}
Enter fullscreen mode Exit fullscreen mode

This code defines a component named Index and displays a text message "Hello World" in the component. Clicking the button will execute the concurrentCalculation function, which creates a concurrent task and executes it. After the task is completed, the result will be output on the console.

Summary

Through the above introduction, you can understand the usage methods of the concurrent capabilities of TaskPool and Worker in the HarmonyOS system. Both TaskPool and Worker are implemented based on the Actor concurrent model, but their usage scenarios and functions are different. Hope this article can help you master the concurrent programming techniques in the HarmonyOS system and develop better HarmonyOS applications.

Top comments (0)