使用任务池

2024-01-23 18:07 更新

任务池(taskpool)作用是为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能,且您无需关心线程实例的生命周期。您可以使用任务池API创建后台任务(Task),并对所创建的任务进行如任务执行、任务取消的操作。理论上您可以使用任务池API创建数量不受限制的任务,但是出于内存因素不建议您这样做。此外,不建议您在任务中执行阻塞操作,特别是无限期阻塞操作,长时间的阻塞操作占据工作线程,可能会阻塞其他任务调度,影响您的应用性能。

您所创建的同一优先级任务的执行顺序可以由您决定,任务真实执行的顺序与您调用任务池API提供的任务执行接口顺序一致。任务默认优先级是MEDIUM。(任务优先级机制暂未支持)

当同一时间待执行的任务数量大于任务池工作线程数量,任务池会根据负载均衡机制进行扩容,增加工作线程数量,减少整体等待时长。同样,当执行的任务数量减少,工作线程数量大于执行任务数量,部分工作线程处于空闲状态,任务池会根据负载均衡机制进行缩容,减少工作线程数量。(负载均衡机制暂未支持)

任务池API以数字形式返回错误码。有关各个错误码的更多信息,请参阅文档语言基础类库错误码

说明

本模块首批接口从API version 9 开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。

导入模块

  1. import taskpool from '@ohos.taskpool';

Priority

表示所创建任务(Task)的优先级。(暂未支持)

系统能力: SystemCapability.Utils.Lang

名称

说明

HIGH

0

任务为高优先级。

MEDIUM

1

任务为中优先级。

LOW

2

任务为低优先级。

Task

表示任务。使用以下方法前,需要先构造Task。

constructor

constructor(func: Function, ...args: unknown[])

Task的构造函数。

系统能力: SystemCapability.Utils.Lang

参数:

参数名

类型

必填

说明

func

Function

任务执行需要传入函数,支持的函数返回值类型请查序列化支持类型

args

unknown[]

任务执行传入函数的参数,支持的参数类型请查序列化支持类型。默认值为undefined。

错误码:

以下错误码的详细介绍请参见语言基础类库错误码

错误码ID

错误信息

10200014

The function is not mark as concurrent.

示例:

  1. @Concurrent
  2. function func(args) {
  3. console.log("func: " + args);
  4. return args;
  5. }
  6. let task = new taskpool.Task(func, "this is my first Task");

属性

系统能力: SystemCapability.Utils.Lang

名称

类型

可读

可写

说明

function

Function

创建任务时需要传入的函数,支持的函数返回值类型请查序列化支持类型

arguments

unknown[]

创建任务传入函数所需的参数,支持的参数类型请查序列化支持类型

taskpool.execute

execute(func: Function, ...args: unknown[]): Promise<unknown>

将待执行的函数放入taskpool内部任务队列等待,等待分发到工作线程执行。当前执行模式不可取消任务。

系统能力: SystemCapability.Utils.Lang

参数:

参数名

类型

必填

说明

func

Function

执行的逻辑需要传入函数,支持的函数返回值类型请查序列化支持类型

args

unknown[]

执行逻辑的函数所需要的参数,支持的参数类型请查序列化支持类型。默认值为undefined。

返回值:

类型

说明

Promise<unknown>

execute是异步方法,返回Promise对象。

错误码:

以下错误码的详细介绍请参见语言基础类库错误码

错误码ID

错误信息

10200003

Worker initialization failure.

10200006

Serializing an uncaught exception failed.

10200014

The function is not mark as concurrent.

示例:

  1. @Concurrent
  2. function func(args) {
  3. console.log("func: " + args);
  4. return args;
  5. }
  6. async function taskpoolTest() {
  7. let value = await taskpool.execute(func, 100);
  8. console.log("taskpool result: " + value);
  9. }
  10. taskpoolTest();

taskpool.execute

execute(task: Task, priority?: Priority): Promise<unknown>

将创建好的任务放入taskpool内部任务队列等待,等待分发到工作线程执行。当前执行模式可尝试调用cancel进行任务取消。

系统能力: SystemCapability.Utils.Lang

参数:

参数名

类型

必填

说明

task

Task

需要在任务池中执行的任务。

priority

Priority

等待执行的任务的优先级(暂未支持)。

返回值:

类型

说明

Promise<unknown>

execute是异步方法,返回Promise对象。

错误码:

以下错误码的详细介绍请参见语言基础类库错误码

错误码ID

错误信息

10200003

Worker initialization failure.

10200006

Serializing an uncaught exception failed.

10200014

The function is not mark as concurrent.

示例:

  1. @Concurrent
  2. function func(args) {
  3. console.log("func: " + args);
  4. return args;
  5. }
  6. async function taskpoolTest() {
  7. let task = new taskpool.Task(func, 100);
  8. let value = await taskpool.execute(task);
  9. console.log("taskpool result: " + value);
  10. }
  11. taskpoolTest();

taskpool.cancel

cancel(task: Task): void

取消任务池中的任务。

系统能力: SystemCapability.Utils.Lang

参数:

参数名

类型

必填

说明

task

Task

需要取消执行的任务。

错误码:

以下错误码的详细介绍请参见语言基础类库错误码

错误码ID

错误信息

10200015

If the task is not exist.

10200016

If the task is running.

任务取消成功示例:

  1. function func(args) {
  2. "use concurrent";
  3. console.log("func: " + args);
  4. return args;
  5. }
  6. async function taskpoolTest() {
  7. let task = new taskpool.Task(func, 100);
  8. taskpool.execute(task);
  9. try {
  10. taskpool.cancel(task);
  11. } catch (e) {
  12. console.log("taskpool.cancel occur error:" + e);
  13. }
  14. }
  15. taskpoolTest();

已执行的任务取消失败示例:

  1. function func(args) {
  2. "use concurrent";
  3. console.log("func: " + args);
  4. return args;
  5. }
  6. async function taskpoolTest() {
  7. let task = new taskpool.Task(func, 100);
  8. let value = taskpool.execute(task);
  9. let start = new Date().getTime();
  10. while (new Date().getTime() - start < 1000) { // 延时1s,确保任务已执行
  11. continue;
  12. }
  13. try {
  14. taskpool.cancel(task); //任务已执行,取消失败
  15. } catch (e) {
  16. console.log("taskpool.cancel occur error:" + e);
  17. }
  18. }
  19. taskpoolTest();

其他说明

序列化支持类型

序列化支持类型包括:All Primitive Type(不包括symbol)、Date、String、RegExp、Array、Map、Set、Object、ArrayBuffer、TypedArray。

注意事项

  • 仅支持在Stage模型且module的compileMode为esmodule的project中使用taskpool api。确认module的compileMode方法:查看当前module的build-profile.json5,在buildOption中补充"compileMode": "esmodule"。
  • taskpool任务只支持引用入参传递或者import的变量,不支持使用闭包变量,使用装饰器@Concurrent进行拦截。
  • taskpool任务只支持普通函数或者async函数,不支持类成员函数或者匿名函数,使用装饰器@Concurrent进行拦截。
  • 装饰器@Concurrent仅支持在ets文件使用,在ts文件中创建taskpool任务需使用"use concurrent"。

简单使用

示例一

  1. // 支持普通函数、引用入参传递
  2. @Concurrent
  3. function func(args) {
  4. console.log("func: " + args);
  5. return args;
  6. }
  7. async function taskpoolTest() {
  8. // taskpool.execute(task)
  9. let task = new taskpool.Task(func, "create task, then execute");
  10. let val1 = await taskpool.execute(task);
  11. console.log("taskpool.execute(task) result: " + val1);
  12. // taskpool.execute(function)
  13. let val2 = await taskpool.execute(func, "execute task by func");
  14. console.log("taskpool.execute(function) result: " + val2);
  15. }
  16. taskpoolTest();

示例二

  1. // b.ets
  2. export let c = 2000;
  1. // 引用import变量
  2. // a.ets(与b.ets位于同一目录中)
  3. import { c } from "./b";
  4. @Concurrent
  5. function test(a) {
  6. console.log(a);
  7. console.log(c);
  8. return a;
  9. }
  10. async function taskpoolTest() {
  11. // taskpool.execute(task)
  12. let task = new taskpool.Task(test, "create task, then execute");
  13. let val1 = await taskpool.execute(task);
  14. console.log("taskpool.execute(task) result: " + val1);
  15. // taskpool.execute(function)
  16. let val2 = await taskpool.execute(test, "execute task by func");
  17. console.log("taskpool.execute(function) result: " + val2);
  18. }
  19. taskpoolTest();

示例三

  1. // 支持async函数
  2. @Concurrent
  3. async function task() {
  4. let ret = await Promise.all([
  5. new Promise(resolve => setTimeout(resolve, 1000, "resolved"))
  6. ]);
  7. return ret;
  8. }
  9. async function taskpoolTest() {
  10. taskpool.execute(task).then((result) => {
  11. console.log("TaskPoolTest task result: " + result);
  12. });
  13. }
  14. taskpoolTest();

示例四

  1. // 在ts文件中创建taskpool任务需使用"use concurrent"
  2. // c.ts
  3. function test1(n) {
  4. "use concurrent"
  5. return n;
  6. }
  7. export async function taskpoolTest1() {
  8. console.log("taskpoolTest1 start");
  9. let task = new taskpool.Task(test1, 100);
  10. let result = await taskpool.execute(task);
  11. console.log("taskpoolTest1 result:" + result);
  12. }
  13. async function test2() {
  14. "use concurrent"
  15. let ret = await Promise.all([
  16. new Promise(resolve => setTimeout(resolve, 1000, "resolved"))
  17. ]);
  18. return ret;
  19. }
  20. export async function taskpoolTest2() {
  21. console.log("taskpoolTest2 start");
  22. taskpool.execute(test2).then((result) => {
  23. console.log("TaskPoolTest2 result: " + result);
  24. });
  25. }
  1. // a.ets(与c.ts在同一目录中)
  2. import { taskpoolTest1, taskpoolTest2 } from "./c";
  3. taskpoolTest1();
  4. taskpoolTest2();
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号