1# @ohos.taskpool(使用任务池) 2 3任务池(taskpool)作用是为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能,且您无需关心线程实例的生命周期。您可以使用任务池API创建后台任务(Task),并对所创建的任务进行如任务执行、任务取消的操作。理论上您可以使用任务池API创建数量不受限制的任务,但是出于内存因素不建议您这样做。此外,不建议您在任务中执行阻塞操作,特别是无限期阻塞操作,长时间的阻塞操作占据工作线程,可能会阻塞其他任务调度,影响您的应用性能。 4 5您所创建的同一优先级任务的执行顺序可以由您决定,任务真实执行的顺序与您调用任务池API提供的任务执行接口顺序一致。任务默认优先级是MEDIUM。(任务优先级机制暂未支持) 6 7当同一时间待执行的任务数量大于任务池工作线程数量,任务池会根据负载均衡机制进行扩容,增加工作线程数量,减少整体等待时长。同样,当执行的任务数量减少,工作线程数量大于执行任务数量,部分工作线程处于空闲状态,任务池会根据负载均衡机制进行缩容,减少工作线程数量。(负载均衡机制暂未支持) 8 9任务池API以数字形式返回错误码。有关各个错误码的更多信息,请参阅文档[语言基础类库错误码](../errorcodes/errorcode-utils.md)。 10 11> **说明:**<br/> 12> 本模块首批接口从API version 9 开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 13 14## 导入模块 15 16```ts 17import taskpool from '@ohos.taskpool'; 18``` 19 20## Priority 21 22表示所创建任务(Task)的优先级。(暂未支持) 23 24**系统能力:** SystemCapability.Utils.Lang 25 26| 名称 | 值 | 说明 | 27| -------- | -------- | -------- | 28| HIGH | 0 | 任务为高优先级。 | 29| MEDIUM | 1 | 任务为中优先级。 | 30| LOW | 2 | 任务为低优先级。 | 31 32## Task 33 34表示任务。使用以下方法前,需要先构造Task。 35 36### constructor 37 38constructor(func: Function, ...args: unknown[]) 39 40Task的构造函数。 41 42**系统能力:** SystemCapability.Utils.Lang 43 44**参数:** 45 46| 参数名 | 类型 | 必填 | 说明 | 47| ------ | --------- | ---- | -------------------------------------------------------------------- | 48| func | Function | 是 | 任务执行需要传入函数,支持的函数返回值类型请查[序列化支持类型](#序列化支持类型)。 | 49| args | unknown[] | 否 | 任务执行传入函数的参数,支持的参数类型请查[序列化支持类型](#序列化支持类型)。默认值为undefined。 | 50 51**错误码:** 52 53以下错误码的详细介绍请参见[语言基础类库错误码](../errorcodes/errorcode-utils.md)。 54 55| 错误码ID | 错误信息 | 56| -------- | --------------------------------------- | 57| 10200014 | The function is not mark as concurrent. | 58 59**示例:** 60 61```ts 62@Concurrent 63function func(args) { 64 console.log("func: " + args); 65 return args; 66} 67 68let task = new taskpool.Task(func, "this is my first Task"); 69``` 70 71### 属性 72 73**系统能力:** SystemCapability.Utils.Lang 74 75| 名称 | 类型 | 可读 | 可写 | 说明 | 76| --------- | --------- | ---- | ---- | ------------------------------------------------------------------------- | 77| function | Function | 是 | 是 | 创建任务时需要传入的函数,支持的函数返回值类型请查[序列化支持类型](#序列化支持类型)。 | 78| arguments | unknown[] | 是 | 是 | 创建任务传入函数所需的参数,支持的参数类型请查[序列化支持类型](#序列化支持类型)。 | 79 80## taskpool.execute 81 82execute(func: Function, ...args: unknown[]): Promise\<unknown> 83 84将待执行的函数放入taskpool内部任务队列等待,等待分发到工作线程执行。当前执行模式不可取消任务。 85 86**系统能力:** SystemCapability.Utils.Lang 87 88**参数:** 89 90| 参数名 | 类型 | 必填 | 说明 | 91| ------ | --------- | ---- | ---------------------------------------------------------------------- | 92| func | Function | 是 | 执行的逻辑需要传入函数,支持的函数返回值类型请查[序列化支持类型](#序列化支持类型)。 | 93| args | unknown[] | 否 | 执行逻辑的函数所需要的参数,支持的参数类型请查[序列化支持类型](#序列化支持类型)。默认值为undefined。 | 94 95**返回值:** 96 97| 类型 | 说明 | 98| ----------------- | ------------------------------------ | 99| Promise\<unknown> | execute是异步方法,返回Promise对象。 | 100 101**错误码:** 102 103以下错误码的详细介绍请参见[语言基础类库错误码](../errorcodes/errorcode-utils.md)。 104 105| 错误码ID | 错误信息 | 106| -------- | ----------------------------------------- | 107| 10200003 | Worker initialization failure. | 108| 10200006 | Serializing an uncaught exception failed. | 109| 10200014 | The function is not mark as concurrent. | 110 111**示例:** 112 113```ts 114@Concurrent 115function func(args) { 116 console.log("func: " + args); 117 return args; 118} 119 120async function taskpoolTest() { 121 let value = await taskpool.execute(func, 100); 122 console.log("taskpool result: " + value); 123} 124 125taskpoolTest(); 126``` 127 128## taskpool.execute 129 130execute(task: Task, priority?: Priority): Promise\<unknown> 131 132将创建好的任务放入taskpool内部任务队列等待,等待分发到工作线程执行。当前执行模式可尝试调用cancel进行任务取消。 133 134**系统能力:** SystemCapability.Utils.Lang 135 136**参数:** 137 138| 参数名 | 类型 | 必填 | 说明 | 139| -------- | --------------------- | ---- | ------------------------------------ | 140| task | [Task](#task) | 是 | 需要在任务池中执行的任务。 | 141| priority | [Priority](#priority) | 否 | 等待执行的任务的优先级(暂未支持)。 | 142 143**返回值:** 144 145| 类型 | 说明 | 146| ---------------- | ------------------------------ | 147| Promise\<unknown> | execute是异步方法,返回Promise对象。 | 148 149**错误码:** 150 151以下错误码的详细介绍请参见[语言基础类库错误码](../errorcodes/errorcode-utils.md)。 152 153| 错误码ID | 错误信息 | 154| -------- | ----------------------------------------- | 155| 10200003 | Worker initialization failure. | 156| 10200006 | Serializing an uncaught exception failed. | 157| 10200014 | The function is not mark as concurrent. | 158 159**示例:** 160 161```ts 162@Concurrent 163function func(args) { 164 console.log("func: " + args); 165 return args; 166} 167 168async function taskpoolTest() { 169 let task = new taskpool.Task(func, 100); 170 let value = await taskpool.execute(task); 171 console.log("taskpool result: " + value); 172} 173 174taskpoolTest(); 175``` 176 177## taskpool.cancel 178 179cancel(task: Task): void 180 181取消任务池中的任务。 182 183**系统能力:** SystemCapability.Utils.Lang 184 185**参数:** 186 187| 参数名 | 类型 | 必填 | 说明 | 188| ------ | ------------- | ---- | -------------------- | 189| task | [Task](#task) | 是 | 需要取消执行的任务。 | 190 191**错误码:** 192 193以下错误码的详细介绍请参见[语言基础类库错误码](../errorcodes/errorcode-utils.md)。 194 195| 错误码ID | 错误信息 | 196| -------- | ------------------------- | 197| 10200015 | If the task is not exist. | 198| 10200016 | If the task is running. | 199 200**任务取消成功示例:** 201 202```ts 203function func(args) { 204 "use concurrent"; 205 console.log("func: " + args); 206 return args; 207} 208 209async function taskpoolTest() { 210 let task = new taskpool.Task(func, 100); 211 taskpool.execute(task); 212 try { 213 taskpool.cancel(task); 214 } catch (e) { 215 console.log("taskpool.cancel occur error:" + e); 216 } 217} 218 219taskpoolTest(); 220``` 221 222**已执行的任务取消失败示例:** 223 224```ts 225function func(args) { 226 "use concurrent"; 227 console.log("func: " + args); 228 return args; 229} 230 231async function taskpoolTest() { 232 let task = new taskpool.Task(func, 100); 233 let value = taskpool.execute(task); 234 let start = new Date().getTime(); 235 while (new Date().getTime() - start < 1000) { // 延时1s,确保任务已执行 236 continue; 237 } 238 239 try { 240 taskpool.cancel(task); //任务已执行,取消失败 241 } catch (e) { 242 console.log("taskpool.cancel occur error:" + e); 243 } 244} 245 246taskpoolTest(); 247``` 248 249**正在执行的任务取消失败示例:** 250 251```ts 252function func(args) { 253 "use concurrent"; 254 console.log("func: " + args); 255 return args; 256} 257 258async function taskpoolTest() { 259 let task1 = new taskpool.Task(func, 100); 260 let task2 = new taskpool.Task(func, 200); 261 let task3 = new taskpool.Task(func, 300); 262 let task4 = new taskpool.Task(func, 400); 263 let task5 = new taskpool.Task(func, 500); 264 let task6 = new taskpool.Task(func, 600); 265 266 let res1 = taskpool.execute(task1); 267 let res2 = taskpool.execute(task2); 268 let res3 = taskpool.execute(task3); 269 let res4 = taskpool.execute(task4); 270 let res5 = taskpool.execute(task5); 271 let res6 = taskpool.execute(task6); 272 try { 273 taskpool.cancel(task1); // task1任务正在执行,取消失败 274 } catch (e) { 275 console.log("taskpool.cancel occur error:" + e); 276 } 277} 278 279taskpoolTest(); 280``` 281 282## 其他说明 283 284### 序列化支持类型 285序列化支持类型包括:All Primitive Type(不包括symbol)、Date、String、RegExp、Array、Map、Set、Object、ArrayBuffer、TypedArray。 286 287### 注意事项 288- 仅支持在Stage模型且module的compileMode为esmodule的project中使用taskpool api。确认module的compileMode方法:查看当前module的build-profile.json5,在buildOption中补充"compileMode": "esmodule"。 289- taskpool任务只支持引用入参传递或者import的变量,不支持使用闭包变量,使用装饰器@Concurrent进行拦截。 290- taskpool任务只支持普通函数或者async函数,不支持类成员函数或者匿名函数,使用装饰器@Concurrent进行拦截。 291- 装饰器@Concurrent仅支持在ets文件使用,在ts文件中创建taskpool任务需使用"use concurrent"。 292 293### 简单使用 294 295**示例一** 296 297```ts 298// 支持普通函数、引用入参传递 299@Concurrent 300function func(args) { 301 console.log("func: " + args); 302 return args; 303} 304 305async function taskpoolTest() { 306 // taskpool.execute(task) 307 let task = new taskpool.Task(func, "create task, then execute"); 308 let val1 = await taskpool.execute(task); 309 console.log("taskpool.execute(task) result: " + val1); 310 311 // taskpool.execute(function) 312 let val2 = await taskpool.execute(func, "execute task by func"); 313 console.log("taskpool.execute(function) result: " + val2); 314} 315 316taskpoolTest(); 317``` 318 319**示例二** 320 321```ts 322// b.ets 323export var c = 2000; 324``` 325```ts 326// 引用import变量 327// a.ets(与b.ets位于同一目录中) 328import { c } from "./b"; 329 330@Concurrent 331function test(a) { 332 console.log(a); 333 console.log(c); 334 return a; 335} 336 337async function taskpoolTest() { 338 // taskpool.execute(task) 339 let task = new taskpool.Task(test, "create task, then execute"); 340 let val1 = await taskpool.execute(task); 341 console.log("taskpool.execute(task) result: " + val1); 342 343 // taskpool.execute(function) 344 let val2 = await taskpool.execute(test, "execute task by func"); 345 console.log("taskpool.execute(function) result: " + val2); 346} 347 348taskpoolTest(); 349``` 350 351**示例三** 352 353```ts 354// 支持async函数 355@Concurrent 356async function task() { 357 let ret = await Promise.all([ 358 new Promise(resolve => setTimeout(resolve, 1000, "resolved")) 359 ]); 360 return ret; 361} 362 363async function taskpoolTest() { 364 taskpool.execute(task).then((result) => { 365 console.log("TaskPoolTest task result: " + result); 366 }); 367} 368 369taskpoolTest(); 370``` 371 372**示例四** 373 374```ts 375// 在ts文件中创建taskpool任务需使用"use concurrent" 376// c.ts 377function test1(n) { 378 "use concurrent" 379 return n; 380} 381export async function taskpoolTest1() { 382 console.log("taskpoolTest1 start"); 383 var task = new taskpool.Task(test1, 100); 384 var result = await taskpool.execute(task); 385 console.log("taskpoolTest1 result:" + result); 386} 387 388async function test2() { 389 "use concurrent" 390 var ret = await Promise.all([ 391 new Promise(resolve => setTimeout(resolve, 1000, "resolved")) 392 ]); 393 return ret; 394} 395export async function taskpoolTest2() { 396 console.log("taskpoolTest2 start"); 397 taskpool.execute(test2).then((result) => { 398 console.log("TaskPoolTest2 result: " + result); 399 }); 400} 401``` 402 403```ts 404// a.ets(与c.ts在同一目录中) 405import { taskpoolTest1, taskpoolTest2 } from "./c"; 406 407taskpoolTest1(); 408taskpoolTest2(); 409```