# @ohos.taskpool (Starting the Task Pool) The task pool provides a multi-thread running environment for applications. It helps reduce resource consumption and improve system performance. It also frees you from caring about the lifecycle of thread instances. You can use the **TaskPool** APIs to create background tasks and perform operations on them, for example, executing or canceling a task. Theoretically, you can create an unlimited number of tasks, but this is not recommended for memory considerations. In addition, you are not advised performing blocking operations in a task, especially indefinite blocking. Long-time blocking operations occupy worker threads and may block other task scheduling, adversely affecting your application performance. You can determine the execution sequence of tasks with the same priority. They are executed in the same sequence as you call the task execution APIs. The default task priority is **MEDIUM**. If the number of tasks to be executed is greater than the number of worker threads in the task pool, the task pool scales out based on load balancing to minimize the waiting duration. Similarly, when the number of tasks to be executed falls below the number of worker threads, the task pool scales in to reduce the number of worker threads. The **TaskPool** APIs return error codes in numeric format. For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). For details about the precautions for using **TaskPool**, see [Precautions for TaskPool](../../arkts-utils/taskpool-introduction.md#precautions-for-taskpool). > **NOTE**
> The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version. ## Modules to Import ```ts import taskpool from '@ohos.taskpool'; ``` ## taskpool.execute execute(func: Function, ...args: Object[]): Promise\ Places the function to be executed in the internal queue of the task pool. The function will be distributed to the worker thread for execution. The function to be executed in this mode cannot be canceled. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | --------- | ---- | ---------------------------------------------------------------------- | | func | Function | Yes | Function to be executed. For details about the supported return value types of the function, see [Sequenceable Data Types](#sequenceable-data-types). | | args | Object[] | No | Arguments of the function. For details about the supported parameter types, see [Sequenceable Data Types](#sequenceable-data-types). The default value is **undefined**.| **Return value** | Type | Description | | ----------------- | ------------------------------------ | | Promise\ | Promise used to return an object that carries the function execution result.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | -------------------------------------------- | | 10200003 | Worker initialization failure. | | 10200006 | An exception occurred during serialization. | | 10200014 | The function is not mark as concurrent. | **Example** ```ts @Concurrent function printArgs(args: number): number { console.info("printArgs: " + args); return args; } taskpool.execute(printArgs, 100).then((value: Object) => { // 100: test number console.info("taskpool result: " + value); }); ``` ## taskpool.execute execute(task: Task, priority?: Priority): Promise\ Places a task in the internal queue of the task pool. The task will be distributed to the worker thread for execution. The task to be executed in this mode can be canceled. The task cannot be a task in a task group or queue. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | -------- | --------------------- | ---- | ---------------------------------------- | | task | [Task](#task) | Yes | Task to be executed. | | priority | [Priority](#priority) | No | Priority of the task. The default value is **taskpool.Priority.MEDIUM**.| **Return value** | Type | Description | | ---------------- | ---------------- | | Promise\ | Promise used to return an object that carries the function execution result.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | ------------------------------------------- | | 10200003 | Worker initialization failure. | | 10200006 | An exception occurred during serialization. | | 10200014 | The function is not mark as concurrent. | **Example** ```ts @Concurrent function printArgs(args: number): number { console.info("printArgs: " + args); return args; } let task: taskpool.Task = new taskpool.Task(printArgs, 100); // 100: test number taskpool.execute(task).then((value: Object) => { console.info("taskpool result: " + value); }); ``` ## taskpool.execute10+ execute(group: TaskGroup, priority?: Priority): Promise Places a task group in the internal queue of the task pool. The task group will be distributed to the worker thread for execution. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | --------- | --------------------------- | ---- | -------------------------------------------------------------- | | group | [TaskGroup](#taskgroup10) | Yes | Task group to be executed. | | priority | [Priority](#priority) | No | Priority of the task group. The default value is **taskpool.Priority.MEDIUM**.| **Return value** | Type | Description | | ---------------- | ---------------------------------- | | Promise\ | Promise used to return an object array that carries the function execution result.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | ------------------------------------------- | | 10200006 | An exception occurred during serialization. | **Example** ```ts @Concurrent function printArgs(args: number): number { console.info("printArgs: " + args); return args; } let taskGroup1: taskpool.TaskGroup = new taskpool.TaskGroup(); taskGroup1.addTask(printArgs, 10); // 10: test number taskGroup1.addTask(printArgs, 20); // 20: test number taskGroup1.addTask(printArgs, 30); // 30: test number let taskGroup2: taskpool.TaskGroup = new taskpool.TaskGroup(); let task1: taskpool.Task = new taskpool.Task(printArgs, 100); // 100: test number let task2: taskpool.Task = new taskpool.Task(printArgs, 200); // 200: test number let task3: taskpool.Task = new taskpool.Task(printArgs, 300); // 300: test number taskGroup2.addTask(task1); taskGroup2.addTask(task2); taskGroup2.addTask(task3); taskpool.execute(taskGroup1).then((res: Array) => { console.info("taskpool execute res is:" + res); }); taskpool.execute(taskGroup2).then((res: Array) => { console.info("taskpool execute res is:" + res); }); ``` ## taskpool.executeDelayed11+ executeDelayed(delayTime: number, task: Task, priority?: Priority): Promise\ Executes a task after a given delay. The task cannot be a task in a task group or queue. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | ----------- | ------------- | ---- | -------------------- | | delayTime | number | Yes | Delay, in ms. | | task | [Task](#task) | Yes | Task to delay.| | priority | [Priority](#priority) | No | Priority of the task. The default value is **taskpool.Priority.MEDIUM**.| **Return value** | Type | Description | | ---------------- | ---------------------------------- | | Promise\ | Promise used to return an object array that carries the function execution result.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID | Error Message | | --------- | -------------------------------- | | 10200028 | The delayTime is less than zero. | **Example** ```ts @Concurrent // import BusinessError import { BusinessError } from '@ohos.base' function printArgs(args: number): void { console.info("printArgs: " + args); } let t: number = Date.now(); console.info("taskpool start time is: " + t); let task: taskpool.Task = new taskpool.Task(printArgs, 100); // 100: test number taskpool.executeDelayed(1000, task).then(() => { // 1000:delayTime is 1000ms console.info("taskpool execute success"); }).catch((e: BusinessError) => { console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`); }) ``` ## taskpool.cancel cancel(task: Task): void Cancels a task in the task pool. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | ------------- | ---- | -------------------- | | task | [Task](#task) | Yes | Task to cancel.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | -------------------------------------------- | | 10200015 | The task does not exist when it is canceled. | | 10200016 | The task is executing when it is canceled. | Since API version 10, error code 10200016 is not reported when this API is called. **Example of canceling an ongoing task** ```ts @Concurrent function inspectStatus(arg: number): number { // Check whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { console.info("task has been canceled before 2s sleep."); return arg + 2; } // 2s sleep let t: number = Date.now(); while (Date.now() - t < 2000) { continue; } // Check again whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { console.info("task has been canceled after 2s sleep."); return arg + 3; } return arg + 1; } let task1: taskpool.Task = new taskpool.Task(inspectStatus, 100); // 100: test number let task2: taskpool.Task = new taskpool.Task(inspectStatus, 200); // 200: test number let task3: taskpool.Task = new taskpool.Task(inspectStatus, 300); // 300: test number let task4: taskpool.Task = new taskpool.Task(inspectStatus, 400); // 400: test number let task5: taskpool.Task = new taskpool.Task(inspectStatus, 500); // 500: test number let task6: taskpool.Task = new taskpool.Task(inspectStatus, 600); // 600: test number taskpool.execute(task1).then((res: Object)=>{ console.info("taskpool test result: " + res); }); taskpool.execute(task2); taskpool.execute(task3); taskpool.execute(task4); taskpool.execute(task5); taskpool.execute(task6); // Cancel the task 1s later. setTimeout(()=>{ taskpool.cancel(task1); }, 1000); ``` ## taskpool.cancel10+ cancel(group: TaskGroup): void Cancels a task group in the task pool. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | ------- | ----------------------- | ---- | -------------------- | | group | [TaskGroup](#taskgroup10) | Yes | Task group to cancel.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | ------------------------------------------------------- | | 10200018 | The task group does not exist when it is canceled. | **Example** ```ts @Concurrent function printArgs(args: number): number { let t: number = Date.now(); while (Date.now() - t < 2000) { continue; } console.info("printArgs: " + args); return args; } let taskGroup1: taskpool.TaskGroup = new taskpool.TaskGroup(); taskGroup1.addTask(printArgs, 10); // 10: test number let taskGroup2: taskpool.TaskGroup = new taskpool.TaskGroup(); taskGroup2.addTask(printArgs, 100); // 100: test number taskpool.execute(taskGroup1).then((res: Array)=>{ console.info("taskGroup1 res is:" + res); }); taskpool.execute(taskGroup2).then((res: Array)=>{ console.info("taskGroup2 res is:" + res); }); setTimeout(()=>{ try { taskpool.cancel(taskGroup2); } catch (e) { console.error("taskGroup.cancel occur error:" + e); } }, 1000); ``` ## taskpool.getTaskPoolInfo10+ getTaskPoolInfo(): TaskPoolInfo Obtains the internal information about this task pool. **System capability**: SystemCapability.Utils.Lang **Return value** | Type | Description | | ----------------------------------- | ------------------ | | [TaskPoolInfo](#taskpoolinfo10) | Internal information about the task pool. | **Example** ```ts let taskpoolInfo: taskpool.TaskPoolInfo = taskpool.getTaskPoolInfo(); ``` ## Priority Enumerates the priorities available for created tasks. **System capability**: SystemCapability.Utils.Lang | Name| Value| Description| | -------- | -------- | -------- | | HIGH | 0 | The task has a high priority.| | MEDIUM | 1 | The task has a medium priority.| | LOW | 2 | The task has a low priority.| **Example** ```ts @Concurrent function printArgs(args: number): number { console.info("printArgs: " + args); return args; } let task: taskpool.Task = new taskpool.Task(printArgs, 100); // 100: test number let highCount = 0; let mediumCount = 0; let lowCount = 0; let allCount = 100; for (let i: number = 0; i < allCount; i++) { taskpool.execute(task, taskpool.Priority.LOW).then((res: Object) => { lowCount++; console.info("taskpool lowCount is :" + lowCount); }); taskpool.execute(task, taskpool.Priority.MEDIUM).then((res: Object) => { mediumCount++; console.info("taskpool mediumCount is :" + mediumCount); }); taskpool.execute(task, taskpool.Priority.HIGH).then((res: Object) => { highCount++; console.info("taskpool highCount is :" + highCount); }); } ``` ## Task Implements a task. Before calling any APIs in **Task**, you must use [constructor](#constructor) to create a **Task** instance. ### constructor constructor(func: Function, ...args: Object[]) A constructor used to create a **Task** instance. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | --------- | ---- | -------------------------------------------------------------------- | | func | Function | Yes | Function to be passed in for task execution. For details about the supported return value types of the function, see [Sequenceable Data Types](#sequenceable-data-types). | | args | Object[] | No | Arguments of the function. For details about the supported parameter types, see [Sequenceable Data Types](#sequenceable-data-types). The default value is **undefined**.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | --------------------------------------- | | 10200014 | The function is not mark as concurrent. | **Example** ```ts @Concurrent function printArgs(args: number): number { console.info("printArgs: " + args); return args; } let task: taskpool.Task = new taskpool.Task(printArgs, "this is my first Task"); ``` ### constructor11+ constructor(name: string, func: Function, ...args: Object[]) A constructor used to create a **Task** instance, with the task name specified. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | -------- | ---- | ------------------------------------------------------------ | | name | string | Yes | Task name. | | func | Function | Yes | Function to be passed in for task execution. For details about the supported return value types of the function, see [Sequenceable Data Types](#sequenceable-data-types).| | args | Object[] | No | Arguments of the function. For details about the supported parameter types, see [Sequenceable Data Types](#sequenceable-data-types). The default value is **undefined**.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | --------------------------------------- | | 10200014 | The function is not mark as concurrent. | **Example** ```ts @Concurrent function printArgs(args: string): string { console.info("printArgs: " + args); return args; } let taskName: string = "taskName"; let task: taskpool.Task = new taskpool.Task(taskName, printArgs, "this is my first Task"); let name: string = task.name; ``` ### isCanceled10+ static isCanceled(): boolean Checks whether the running task is canceled. Before using this API, you must create a **Task** instance. **System capability**: SystemCapability.Utils.Lang **Return value** | Type | Description | | ------- | ------------------------------------ | | boolean | Returns **true** if the running task is canceled; returns **false** otherwise.| **Example** ```ts @Concurrent function inspectStatus(arg: number): number { // do something if (taskpool.Task.isCanceled()) { console.info("task has been canceled."); // do something return arg + 1; } // do something return arg; } ``` > **NOTE**
> **isCanceled** must be used together with **taskpool.cancel**. If **cancel** is not called, **isCanceled** returns **false** by default. **Example** ```ts @Concurrent function inspectStatus(arg: number): number { // Check whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { console.info("task has been canceled before 2s sleep."); return arg + 2; } // Wait for 2s. let t: number = Date.now(); while (Date.now() - t < 2000) { continue; } // Check again whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { console.info("task has been canceled after 2s sleep."); return arg + 3; } return arg + 1; } let task: taskpool.Task = new taskpool.Task(inspectStatus, 100); // 100: test number taskpool.execute(task).then((res: Object)=>{ console.info("taskpool test result: " + res); }).catch((err: string) => { console.error("taskpool test occur error: " + err); }); // If cancel is not called, isCanceled() returns false by default, and the task execution result is 101. ``` ### setTransferList10+ setTransferList(transfer?: ArrayBuffer[]): void Sets the task transfer list. Before using this API, you must create a **Task** instance. > **NOTE**
> This API is used to set the task transfer list in the form of **ArrayBuffer** in the task pool. The **ArrayBuffer** instance does not copy the content in the task to the worker thread during transfer. Instead, it transfers the buffer control right to the worker thread. After the transfer, the **ArrayBuffer** instance becomes invalid. An empty **ArrayBuffer** will not be transferred. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | -------- | ------------- | ---- | --------------------------------------------- | | transfer | ArrayBuffer[] | No | **ArrayBuffer** instance holding the objects to transfer. The default value is an empty array.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | -------------------------------------------------------------- | | 10200029 | Can not set an arraybuffer to both transferList and cloneList. | **Example** ```ts @Concurrent function testTransfer(arg1: ArrayBuffer, arg2: ArrayBuffer): number { console.info("testTransfer arg1 byteLength: " + arg1.byteLength); console.info("testTransfer arg2 byteLength: " + arg2.byteLength); return 100; } let buffer: ArrayBuffer = new ArrayBuffer(8); let view: Uint8Array = new Uint8Array(buffer); let buffer1: ArrayBuffer = new ArrayBuffer(16); let view1: Uint8Array = new Uint8Array(buffer1); console.info("testTransfer view byteLength: " + view.byteLength); console.info("testTransfer view1 byteLength: " + view1.byteLength); let task: taskpool.Task = new taskpool.Task(testTransfer, view, view1); task.setTransferList([view.buffer, view1.buffer]); taskpool.execute(task).then((res: Object)=>{ console.info("test result: " + res); }).catch((e: string)=>{ console.error("test catch: " + e); }) console.info("testTransfer view byteLength: " + view.byteLength); console.info("testTransfer view1 byteLength: " + view1.byteLength); ``` ### setCloneList11+ setCloneList(cloneList: Object[] | ArrayBuffer[]): void Sets the task clone list. Before using this API, you must create a **Task** instance. > **NOTE**
> Currently, only clone is supported. This API must be used together with [@Sendable decorator](../../arkts-utils/arkts-sendable.md). Otherwise, an exception is thrown. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | --------- | ------------------------ | ---- | --------------------------------------------- | | cloneList | Object[] \| ArrayBuffer[] | Yes| - The type of the passed-in array must be [SendableClass](../../arkts-utils/arkts-sendable.md#basic-concepts) or ArrayBuffer.
- For **SendableClass** instances or **ArrayBuffer** objects held by all objects passed in to the clone list, the inter-thread transmission behavior changes to the clone operation. This means that any modification to the transmitted objects does not affect the original objects.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | -------------------------------------------------------------- | | 10200029 | Can not set an arraybuffer to both transferList and cloneList. | **Example** ```ts import taskpool from '@ohos.taskpool' import { BusinessError } from '@ohos.base' @Sendable class BaseClass { private str: string = "sendable: BaseClass"; static num :number = 10; str1: string = "sendable: this is BaseClass's string"; num1: number = 5; isDone1: boolean = false; private fibonacciRecursive(n: number): number { if (n <= 1) { return n; } else { return this.fibonacciRecursive(n - 1) + this.fibonacciRecursive(n - 2); } } private privateFunc(num: number): number{ let res: number = this.fibonacciRecursive(num); console.info("sendable: BaseClass privateFunc res is: " + res); return res; } publicFunc(num: number): number { return this.privateFunc(num); } get GetNum(): number { return this.num1; } set SetNum(num: number) { this.num1 = num; } constructor(){ console.info(this.str); this.isDone1 = true; } } @Sendable class DeriveClass extends BaseClass { name: string = "sendable: this is DeriveClass"; printName() { console.info(this.name); } constructor() { super(); } } @Concurrent function testFunc(arr: Array, num: number): number { let baseInstance1 = arr[0]; console.info("sendable: str1 is: " + baseInstance1.str1); baseInstance1.SetNum = 100; console.info("sendable: num1 is: " + baseInstance1.GetNum); console.info("sendable: isDone1 is: " + baseInstance1.isDone1); // Obtain the result of the item specified by num from Fibonacci sequence. let res: number = baseInstance1.publicFunc(num); return res; } @Concurrent function printLog(arr: Array): void { let deriveInstance = arr[0]; deriveInstance.printName(); } @Entry @Component struct Index { @State message: string = 'Hello World' build() { Row() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) Button() { Text("TaskPool Test") }.onClick(() => { // task1 calls BaseClass.str1/BaseClass.SetNum/BaseClass.GetNum/BaseClass.isDone1/BaseClass.publicFunc. let baseInstance1: BaseClass = new BaseClass(); let array1 = new Array(); array1.push(baseInstance1); let task1 = new taskpool.Task(testFunc, array1, 10); task1.setCloneList(array1); taskpool.execute(task1).then((res: Object) => { console.info("sendable: task1 res is: " + res); }).catch((e:BusinessError) => { console.error(`sendable: task1 execute Code is ${e.code}, message is ${e.message}`); }) // task2 calls DeriveClass.printName. let deriveInstance: DeriveClass = new DeriveClass(); let array2 = new Array(); array2.push(deriveInstance); let task2 = new taskpool.Task(printLog, array2); task2.setCloneList(array2); taskpool.execute(task2).then(() => { console.info("sendable: task2 execute success"); }).catch((e:BusinessError) => { console.error(`sendable: task2 execute Code is ${e.code}, message is ${e.message}`); }) }) .height('15%') .width('30%') } .width('100%') } .height('100%') } } ``` ### sendData11+ static sendData(...args: Object[]): void Sends data to the host thread and triggers the registered callback. Before using this API, you must create a **Task** instance. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | -------- | ------------- | ---- | ------------------------------------------------- | | args | Object[] | Yes | Data to be used as the input parameter of the registered callback. For details about the supported parameter types, see [Sequenceable Data Types](#sequenceable-data-types).| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | --------------------------------------- | | 10200006 | An exception occurred during serialization. | | 10200022 | The function is not called in the taskpool thread. | | 10200023 | The function is not called in the concurrent function. | | 10200024 | The callback is not registered on the host side. | **Example** ```ts @Concurrent function ConcurrentFunc(num: number): number { let res: number = num * 10; taskpool.Task.sendData(res); return num; } ``` ### onReceiveData11+ onReceiveData(callback?: Function): void Registers a callback for a task to receive and process data from the worker thread. Before using this API, you must create a **Task** instance. > **NOTE**
> If multiple callbacks are registered for the same task, only the last registration takes effect. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | -------- | -------- | ---- | ------------------------------------------------------------ | | callback | Function | No | Callback function for processing the data received. The data sent to the host thread is transferred to the callback as an input parameter. If no value is passed in, all the registered callbacks are canceled.| **Example** ```ts @Concurrent function ConcurrentFunc(num: number): number { let res: number = num * 10; taskpool.Task.sendData(res); return num; } function pringLog(data: number): void { console.info("taskpool: data is: " + data); } async function testFunc(): Promise { try { let task: taskpool.Task = new taskpool.Task(ConcurrentFunc, 1); task.onReceiveData(pringLog); await taskpool.execute(task); } catch (e) { console.info(`taskpool: error code: ${e.code}, info: ${e.message}`); } } testFunc(); ``` ### addDependency11+ addDependency(...tasks: Task[]): void Adds dependent tasks for this task. Before using this API, you must create a **Task** instance. The task cannot be a task in a task group or queue, or a task that has been executed. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | ------------------ | | tasks | [Task](#task)[] | Yes | Array of tasks on which the current task depends.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | ------------------------------- | | 10200026 | There is a circular dependency. | **Example** ```ts @Concurrent function delay(args: number): number { let t: number = Date.now(); while ((Date.now() - t) < 1000) { continue; } return args; } let task1:taskpool.Task = new taskpool.Task(delay, 100); let task2:taskpool.Task = new taskpool.Task(delay, 200); let task3:taskpool.Task = new taskpool.Task(delay, 200); console.info("dependency: add dependency start"); task1.addDependency(task2); task2.addDependency(task3); console.info("dependency: add dependency end"); console.info("dependency: start execute second") taskpool.execute(task1).then(() => { console.info("dependency: second task1 success"); }) taskpool.execute(task2).then(() => { console.info("dependency: second task2 success"); }) taskpool.execute(task3).then(() => { console.info("dependency: second task3 success"); }) ``` ### removeDependency11+ removeDependency(...tasks: Task[]): void Removes dependent tasks for this task. Before using this API, you must create a **Task** instance. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | ------------------ | | tasks | [Task](#task)[] | Yes | Array of tasks on which the current task depends.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | ------------------------------ | | 10200027 | The dependency does not exist. | **Example** ```ts @Concurrent function delay(args: number): number { let t: number = Date.now(); while ((Date.now() - t) < 1000) { continue; } return args; } let task1:taskpool.Task = new taskpool.Task(delay, 100); let task2:taskpool.Task = new taskpool.Task(delay, 200); let task3:taskpool.Task = new taskpool.Task(delay, 200); console.info("dependency: add dependency start"); task1.addDependency(task2); task2.addDependency(task3); console.info("dependency: add dependency end"); console.info("dependency: remove dependency start"); task1.removeDependency(task2); task2.removeDependency(task3); console.info("dependency: remove dependency end"); console.info("dependency: start execute") taskpool.execute(task1).then(() => { console.info("dependency: task1 success"); }) taskpool.execute(task2).then(() => { console.info("dependency: task2 success"); }) taskpool.execute(task3).then(() => { console.info("dependency: task3 success"); }) ``` ### Attributes **System capability**: SystemCapability.Utils.Lang | Name | Type | Readable| Writable| Description | | -------------------- | --------- | ---- | ---- | ------------------------------------------------------------ | | function | Function | Yes | Yes | Function to be passed in during task creation. For details about the supported return value types of the function, see [Sequenceable Data Types](#sequenceable-data-types).| | arguments | Object[] | Yes | Yes | Arguments of the function. For details about the supported parameter types, see [Sequenceable Data Types](#sequenceable-data-types).| | name11+ | string | Yes | Yes | Name of the task specified when the task is created. | | totalDuration11+ | number | Yes | No | Total execution time of the task. | | ioDuration11+ | number | Yes | No | Asynchronous I/O time of the task. | | cpuDuration11+ | number | Yes | No | CPU time of the task. | ## TaskGroup10+ Implements a task group, in which all tasks are executed at a time. If all the tasks are executed normally, an array of task results is returned asynchronously, and the sequence of elements in the array is the same as the sequence of tasks added by calling [addTask](#addtask10-1). If any task fails, the corresponding exception is thrown. A task group can be executed for multiple times, but no task can be added after the task group is executed. Before calling any APIs in **TaskGroup**, you must use [constructor](#constructor10) to create a **TaskGroup** instance. ### constructor10+ constructor() Constructor used to create a **TaskGroup** instance. **System capability**: SystemCapability.Utils.Lang **Example** ```ts let taskGroup = new taskpool.TaskGroup(); ``` ### constructor11+ constructor(name: string) A constructor used to create a **TaskGroup** instance, with the task group name specified. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | ------------ | | name | string | Yes | Task group name.| **Example** ```ts let taskGroupName: string = "groupName"; let taskGroup: taskpool.TaskGroup = new taskpool.TaskGroup(taskGroupName); let name: string = taskGroup.name; ``` ### addTask10+ addTask(func: Function, ...args: Object[]): void Adds the function to be executed to this task group. Before using this API, you must create a **TaskGroup** instance. Tasks in another task group or queue, dependent tasks, and tasks that have been executed cannot be added to the task group. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | --------- | ---- | ---------------------------------------------------------------------- | | func | Function | Yes | Function to be passed in for task execution. For details about the supported return value types of the function, see [Sequenceable Data Types](#sequenceable-data-types). | | args | Object[] | No | Arguments of the function. For details about the supported parameter types, see [Sequenceable Data Types](#sequenceable-data-types). The default value is **undefined**.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | --------------------------------------- | | 10200014 | The function is not mark as concurrent. | **Example** ```ts @Concurrent function printArgs(args: number): number { console.info("printArgs: " + args); return args; } let taskGroup: taskpool.TaskGroup = new taskpool.TaskGroup(); taskGroup.addTask(printArgs, 100); // 100: test number ``` ### addTask10+ addTask(task: Task): void Adds a created task to this task group. Before using this API, you must create a **TaskGroup** instance. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | -------- | --------------------- | ---- | ---------------------------------------- | | task | [Task](#task) | Yes | Task to be added to the task group. | **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | --------------------------------------- | | 10200014 | The function is not mark as concurrent. | **Example** ```ts @Concurrent function printArgs(args: number): number { console.info("printArgs: " + args); return args; } let taskGroup: taskpool.TaskGroup = new taskpool.TaskGroup(); let task: taskpool.Task = new taskpool.Task(printArgs, 200); // 200: test number taskGroup.addTask(task); ``` ### Attributes **System capability**: SystemCapability.Utils.Lang | Name| Type | Readable| Writable| Description | | ---- | ------ | ---- | ---- | ---------------------------- | | name11+ | string | Yes | Yes | Name of the task group specified when the task group is created.| ## SequenceRunner 11+ Implements a queue that executes the tasks in sequence. Before calling any APIs in **SequenceRunner**, you must use [constructor](#constructor11-3) to create a **SequenceRunner** instance. ### constructor11+ constructor(priority?: Priority) A constructor used to create a **SequenceRunner** instance. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name | Type | Mandatory| Description | | -------- | --------------------- | ---- | ---------------------------------------------------------- | | priority | [Priority](#priority) | No | Priority of the task. The default value is **taskpool.Priority.MEDIUM**.| **Example** ```ts let runner: taskpool.SequenceRunner = new taskpool.SequenceRunner(); ``` ### execute11+ execute(task: Task): Promise\ Adds a task to the queue for execution. Before using this API, you must create a **SequenceRunner** instance. Tasks in another task group or queue, dependent tasks, and tasks that have been executed cannot be added to the queue. > **NOTE** > > - Tasks that depend others cannot be added to the queue. > - The failure or cancellation of a task does not affect the execution of subsequent tasks in the queue. **System capability**: SystemCapability.Utils.Lang **Parameters** | Name| Type | Mandatory| Description | | ------ | ------------- | ---- | -------------------------------- | | task | [Task](#task) | Yes | Task to be added to the queue.| **Return value** | Type | Description | | ---------------- | --------------------------------- | | Promise\ | Promise used to return the task execution result.| **Error codes** For details about the error codes, see [Utils Error Codes](../errorcodes/errorcode-utils.md). | ID| Error Message | | -------- | ------------------------------------------- | | 10200003 | Worker initialization failure. | | 10200006 | An exception occurred during serialization. | | 10200025 | Add dependent task to SequenceRunner. | **Example** ```ts @Concurrent function additionDelay(delay:number): void { let start: number = new Date().getTime(); while (new Date().getTime() - start < delay) { continue; } } @Concurrent function waitForRunner(finalString: string): string { return finalString; } async function seqRunner() { let finalString:string = ""; let task1:taskpool.Task = new taskpool.Task(additionDelay, 3000); let task2:taskpool.Task = new taskpool.Task(additionDelay, 2000); let task3:taskpool.Task = new taskpool.Task(additionDelay, 1000); let task4:taskpool.Task = new taskpool.Task(waitForRunner, finalString); let runner:taskpool.SequenceRunner = new taskpool.SequenceRunner(); runner.execute(task1).then(() => { finalString += 'a'; console.info("seqrunner: task1 done."); }); runner.execute(task2).then(() => { finalString += 'b'; console.info("seqrunner: task2 done"); }); runner.execute(task3).then(() => { finalString += 'c'; console.info("seqrunner: task3 done"); }); await runner.execute(task4); console.info("seqrunner: task4 done, finalString is " + finalString); } ``` ## State10+ Enumerates the task states. **System capability**: SystemCapability.Utils.Lang | Name | Value | Description | | --------- | -------- | ------------- | | WAITING | 1 | The task is waiting.| | RUNNING | 2 | The task is running.| | CANCELED | 3 | The task is canceled.| ## TaskInfo10+ Describes the internal information about a task. **System capability**: SystemCapability.Utils.Lang ### Attributes **System capability**: SystemCapability.Utils.Lang | Name | Type | Readable| Writable| Description | | -------- | ------------------ | ---- | ---- | ------------------------------------------------------------- | | taskId | number | Yes | No | Task ID. | | state | [State](#state10) | Yes | No | Task state. | | duration | number | Yes | No | Duration that the task has been executed, in ms. If the return value is **0**, the task is not running. If the return value is empty, no task is running. | ## ThreadInfo10+ Describes the internal information about a worker thread. **System capability**: SystemCapability.Utils.Lang ### Attributes **System capability**: SystemCapability.Utils.Lang | Name | Type | Readable| Writable| Description | | -------- | ---------------------- | ---- | ---- | -------------------------------------------------------- | | tid | number | Yes | No | ID of the worker thread. If the return value is empty, no task is running. | | taskIds | number[] | Yes | No | IDs of tasks running on the calling thread. If the return value is empty, no task is running. | | priority | [Priority](#priority) | Yes | No | Priority of the calling thread. If the return value is empty, no task is running. | ## TaskPoolInfo10+ Describes the internal information about a task pool. **System capability**: SystemCapability.Utils.Lang ### Attributes **System capability**: SystemCapability.Utils.Lang | Name | Type | Readable| Writable| Description | | ------------- | -------------------------------- | ---- | ---- | -------------------- | | threadInfos | [ThreadInfo[]](#threadinfo10) | Yes | No | Internal information about the worker threads. | | taskInfos | [TaskInfo[]](#taskinfo10) | Yes | No | Internal information about the tasks. | ## Additional Information ### Sequenceable Data Types The following sequenceable data types are supported: All Primitive Type (excluding symbol), Date, String, RegExp, Array, Map, Set, Object, ArrayBuffer, and TypedArray. ### Using the Task Pool in Simple Mode **Example 1** ```ts // Common functions are supported, and variables passed in by input parameters are also supported. @Concurrent function printArgs(args: number): number { console.info("func: " + args); return args; } async function taskpoolExecute(): Promise { // taskpool.execute(task) let task: taskpool.Task = new taskpool.Task(printArgs, "create task, then execute"); console.info("taskpool.execute(task) result: " + await taskpool.execute(task)); // taskpool.execute(function) console.info("taskpool.execute(function) result: " + await taskpool.execute(printArgs, "execute task by func")); } taskpoolExecute(); ``` **Example 2** ```ts // b.ets export let c: string = "hello"; ``` ```ts // Reference an imported variable. // a.ets (in the same directory as b.ets) import { c } from "./b"; @Concurrent function printArgs(a: string): string { console.info(a); console.info(c); return a; } async function taskpoolExecute(): Promise { // taskpool.execute(task) let task: taskpool.Task = new taskpool.Task(printArgs, "create task, then execute"); console.info("taskpool.execute(task) result: " + await taskpool.execute(task)); // taskpool.execute(function) console.info("taskpool.execute(function) result: " + await taskpool.execute(printArgs, "execute task by func")); } taskpoolExecute(); ``` **Example 3** ```ts // The async functions are supported. @Concurrent async function delayExcute(): Promise { let ret = await Promise.all([ new Promise(resolve => setTimeout(resolve, 1000, "resolved")) ]); return ret; } async function taskpoolExecute(): Promise { taskpool.execute(delayExcute).then((result: Object) => { console.info("taskPoolTest task result: " + result); }).catch((err: string) => { console.error("taskpool test occur error: " + err); }); } taskpoolExecute(); ``` **Example 4** ```ts // c.ets import taskpool from '@ohos.taskpool'; @Concurrent function strSort(inPutArr: Array): Array { let newArr = inPutArr.sort(); return newArr; } export async function func1(): Promise { console.info("taskpoolTest start"); let strArray: Array = ['c test string', 'b test string', 'a test string']; let task: taskpool.Task = new taskpool.Task(strSort, strArray); console.info("func1 result:" + await taskpool.execute(task)); } export async function func2(): Promise { console.info("taskpoolTest2 start"); let strArray: Array = ['c test string', 'b test string', 'a test string']; taskpool.execute(strSort, strArray).then((result: Object) => { console.info("func2 result: " + result); }).catch((err: string) => { console.error("taskpool test occur error: " + err); }); } ``` ```ts // index.ets import { func1, func2 } from "./c"; func1(); func2(); ``` **Example 5** ```ts // Success in canceling a task @Concurrent function inspectStatus(arg: number): number { // Check whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { console.info("task has been canceled before 2s sleep."); return arg + 2; } // 2s sleep let t: number = Date.now(); while (Date.now() - t < 2000) { continue; } // Check again whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { console.info("task has been canceled after 2s sleep."); return arg + 3; } return arg + 1; } async function taskpoolCancel(): Promise { let task: taskpool.Task = new taskpool.Task(inspectStatus, 100); // 100: test number taskpool.execute(task).then((res: Object)=>{ console.info("taskpool test result: " + res); }).catch((err: string) => { console.error("taskpool test occur error: " + err); }); // Cancel the task 1s later. setTimeout(()=>{ taskpool.cancel(task);}, 1000); } taskpoolCancel(); ``` **Example 6** ```ts // Failure to cancel a task that has been executed @Concurrent function inspectStatus(arg: number): number { // Check whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { return arg + 2; } // Wait for 2s. let t: number = Date.now(); while (Date.now() - t < 500) { continue; } // Check again whether the task has been canceled and respond accordingly. if (taskpool.Task.isCanceled()) { return arg + 3; } return arg + 1; } async function taskpoolCancel(): Promise { let task: taskpool.Task = new taskpool.Task(inspectStatus, 100); // 100: test number taskpool.execute(task).then((res: Object)=>{ console.info("taskpool test result: " + res); }).catch((err: string) => { console.error("taskpool test occur error: " + err); }); setTimeout(()=>{ try { taskpool.cancel(task); // The task has been executed and fails to be canceled. } catch (e) { console.error("taskpool.cancel occur error:" + e); } }, 3000); // Wait for 3s to ensure that the task has been executed. } taskpoolCancel(); ``` **Example 7** ```ts // Success of canceling a task group to be executed @Concurrent function printArgs(args: number): number { let t: number = Date.now(); while (Date.now() - t < 1000) { continue; } console.info("printArgs: " + args); return args; } async function taskpoolGroupCancelTest(): Promise { let taskGroup1: taskpool.TaskGroup = new taskpool.TaskGroup(); taskGroup1.addTask(printArgs, 10); // 10: test number taskGroup1.addTask(printArgs, 20); // 20: test number taskGroup1.addTask(printArgs, 30); // 30: test number let taskGroup2: taskpool.TaskGroup = new taskpool.TaskGroup(); let task1: taskpool.Task = new taskpool.Task(printArgs, 100); // 100: test number let task2: taskpool.Task = new taskpool.Task(printArgs, 200); // 200: test number let task3: taskpool.Task = new taskpool.Task(printArgs, 300); // 300: test number taskGroup2.addTask(task1); taskGroup2.addTask(task2); taskGroup2.addTask(task3); taskpool.execute(taskGroup1).then((res: Array) => { console.info("taskpool execute res is:" + res); }).catch((e: string) => { console.error("taskpool execute error is:" + e); }); taskpool.execute(taskGroup2).then((res: Array) => { console.info("taskpool execute res is:" + res); }).catch((e: string) => { console.error("taskpool execute error is:" + e); }); taskpool.cancel(taskGroup2); } taskpoolGroupCancelTest() ``` **Example 8** ```ts // Create and execute 100 tasks with different priorities, and view their information. @Concurrent function delay(): void { let start: number = new Date().getTime(); while (new Date().getTime() - start < 500) { continue; } } let highCount: number = 0; let mediumCount: number = 0; let lowCount: number = 0; let allCount: number = 100; for (let i = 0; i < allCount; i++) { let task1: taskpool.Task = new taskpool.Task(delay); let task2: taskpool.Task = new taskpool.Task(delay); let task3: taskpool.Task = new taskpool.Task(delay); taskpool.execute(task1, taskpool.Priority.LOW).then(() => { lowCount++; }).catch((e: string) => { console.error("low task error: " + e); }) taskpool.execute(task2, taskpool.Priority.MEDIUM).then(() => { mediumCount++; }).catch((e: string) => { console.error("medium task error: " + e); }) taskpool.execute(task3, taskpool.Priority.HIGH).then(() => { highCount++; }).catch((e: string) => { console.error("high task error: " + e); }) } let start: number = new Date().getTime(); while (new Date().getTime() - start < 1000) { continue; } let taskpoolInfo: taskpool.TaskPoolInfo = taskpool.getTaskPoolInfo(); let tid: number = 0; let taskIds: Array = []; let priority: number = 0; let taskId: number = 0; let state: number = 0; let duration: number = 0; let threadIS = Array.from(taskpoolInfo.threadInfos) for(let threadInfo of threadIS) { tid = threadInfo.tid; if (threadInfo.taskIds != undefined && threadInfo.priority != undefined ) { taskIds.length = threadInfo.taskIds.length; priority = threadInfo.priority; } console.info("taskpool---tid is:" + tid + ", taskIds is:" + taskIds + ", priority is:" + priority); } let taskIS = Array.from(taskpoolInfo.taskInfos) for(let taskInfo of taskIS) { taskId = taskInfo.taskId; state = taskInfo.state; if (taskInfo.duration != undefined ) { duration = taskInfo.duration; } console.info("taskpool---taskId is:" + taskId + ", state is:" + state + ", duration is:" + duration); } ```