TaskPool 使用指南
场景应用
TaskPool 是一个用于任务调度和管理的工具,适用于以下场景:
- 优先级任务处理:如图像库直方图绘制,后台计算的直方图数据对前台界面显示至关重要,影响用户体验,需高优先级处理。
- 频繁取消的任务:在图库大图浏览中,为提升体验,会同时缓存当前图片左右侧各2张图片,滑动切换时需取消另一侧的缓存任务。
- 大量或分散的任务:大型应用的多个模块包含多个耗时任务,不便于使用固定数量的Worker进行负载管理。
- 耗时任务:适用于耗时不超过3分钟的任务。
基本使用
TaskPool 的基本使用包括创建任务、执行任务和取消任务。
// 使用@Concurrent并发装饰器注解并发方法
@Concurrent
function add(num1: number, num2: number): number {
return num1 + num2;
}
// 创建任务
let task: taskpool.Task = new taskpool.Task(add, 1, 2);
async function ConcurrentFunc(): Promise<void> {
try {
// 执行任务
let result = await taskpool.execute(task);
} catch (e) {
console.error("taskpool execute error is: " + e);
}
}
// 取消任务执行
taskpool.cancel(task);
数据克隆
TaskPool 在执行任务时会对传入的数据进行克隆,确保异步方法内对数据的修改不会影响主线程的数据。
@Concurrent
function testFun(list: ShopItemData): ShopItemData {
list.title = "并发后";
return list;
}
// 在组件中使用TaskPool
@Entry
@Component
struct TaskPoolPage {
testData: ShopItemData = new ShopItemData("", "", "", "");
build() {
Row() {
Column() {
Button("TaskPool调用").onClick(() => {
this.testData.title = "并发前";
this.concurrentFunc();
});
}
.width('100%');
}
.height('100%');
}
async concurrentFunc() {
let task: taskpool.Task = new taskpool.Task(testFun, this.testData);
let result = await taskpool.execute(task) as ShopItemData;
console.info("TaskPool返回的值为:" + result.title);
console.info("this.testData的值为:" + this.testData.title);
}
}
支持的数据类型
并发函数的参数和返回值仅支持特定的数据类型,详见官方文档。
其他特性
- 数据传输限制:序列化传输的数据量大小限制为16MB。
- 任务回收:超长任务(大于3分钟)会被系统自动回收。
- 负载均衡:TaskPool支持自动扩缩容,理论上可以创建数量不受限制的任务,但出于内存考虑,不建议创建过多任务。
TaskPool 是一个强大的任务调度工具,能够有效地管理并发任务,提升应用性能和用户体验。