Harmonyos之TaskPool浅学
概述
在开发过程中,多线程是我们非常常见的一种技术。
当前ArkTS提供了TaskPool
和Worker
两种并发能力,下面 我们来探索下TaskPool
的使用方式。
参考链接:
TaskPool的使用
延时任务(executeDelayed)
官方API:
// delayTime: 延时时间 单位毫秒
// task: 需要延时执行的任务
// priority: 延时执行任务的优先级
executeDelayed(delayTime: number, task: Task, priority?: Priority): Promise<Object>
- 无参数、无返回值延时任务
delayedTask() {
console.log('START====================' + DateUtil.getFormatDateStr(new Date()))
//1. 首先我们需要创建一个延时任务
//Task表示任务, 必须要使用concurrent方法来构造Task, 也就是使用@Concurrent修饰的函数
const delayedTask = new taskpool.Task(delayedFunc)
// 执行这个延时任务
taskpool.executeDelayed(2000, delayedTask, taskpool.Priority.HIGH).then((res) => {
console.log('END====================' + DateUtil.getFormatDateStr(new Date()))
})
}
// 延时任务函数
@Concurrent
function delayedFunc(): void {
console.log('delayedFunc =================被执行')
}
输出结果:
- 有参数、有返回值的延时任务
delayedTaskParam() {
console.log('START====================' + DateUtil.getFormatDateStr(new Date()))
//1. 首先我们需要创建一个延时任务
//Task表示任务, 必须要使用concurrent方法来构造Task, 也就是使用@Concurrent修饰的函数
const delayedTask = new taskpool.Task(delayedFundParam, 100, 200)
// 执行这个延时任务
// 其实除了通过.then方法获取返回值时, Arkts还提供了另外一种方式:onReceiveData, 注册回调的方式来接受值,需要再任务执行函数中调用taskpool.Task.sendData(xxx); 可以参考官方文档。
taskpool.executeDelayed(2000, delayedTask, taskpool.Priority.HIGH).then((res) => {
// res是task任务执行后的结果
console.log("res=======================" + JSON.stringify(res))
console.log('END====================' + DateUtil.getFormatDateStr(new Date()))
})
}
// 延时执行函数
@Concurrent
function delayedFundParam(a: number, b: number) : number {
console.log('delayedFundParam =================被执行')
return a + b
}
输出结果:
注意: 在延时任务还没有调用执行的时候, 我们可以通过调用taskpool.cancel(delayedTask )
来取消该延时任务。
优先级任务(Prioity)
- 创建优先级的任务示例:
// 优先级任务
priorityTask() {
// 创建一个优先级的任务
for (let i = 0; i < 9; i+=3) {
this.taskArray.push(new taskpool.Task(priorityFunc, `高优先级${i}`));
this.taskArray.push(new taskpool.Task(priorityFunc, `中优先级${i + 1}`));
this.taskArray.push(new taskpool.Task(priorityFunc, `低优先级${i + 2}`));
}
//执行所有的任务
for (let i = 0; i < this.taskArray.length; i += 3) {
taskpool.execute(this.taskArray[i], taskpool.Priority.HIGH).then(async (res: object) => {
});
taskpool.execute(this.taskArray[i+1], taskpool.Priority.MEDIUM).then(async (res: object) => {
});
taskpool.execute(this.taskArray[i+2], taskpool.Priority.LOW).then(async (res: object) => {
});
}
}
// 执行任务函数
@Concurrent
function priorityFunc(value: string) {
console.log(`======================${value}:任务被执行`)
}
输出结果:
依赖任务(Dependent)
- 创建依赖任务示例:
// 依赖任务示例
dependentTask() {
// 创建依赖任务
for (let i = 0; i < 5; i++) {
const task = new taskpool.Task(dependentFunc, i)
this.taskArray.push(task)
if (i > 0) {
// 创建任务的依赖关系
task.addDependency(this.taskArray[i - 1])
}
}
// 执行任务
for (let index = 0; index < this.taskArray.length; index++) {
const element = this.taskArray[index];
taskpool.execute(element, taskpool.Priority.HIGH).then((res) => {
})
}
}
// task任务执行函数
@Concurrent
function dependentFunc(value: number) {
console.log(`======================${value}:任务被执行`)
}
输出结果:
任务组(TaskGroup)
- 任务组(TaskGroup)示例:
// 创建一个任务组
private taskGroup: taskpool.TaskGroup = new taskpool.TaskGroup();
// 任务组
groupTask() {
for (let i = 0; i < 10; i++) {
this.taskArray.push(new taskpool.Task(taskGroupFunc, i));
this.taskArray[i].onReceiveData((value: string) => {
console.log('value=====================' + value)
})
// 把task任务添加到TaskGroup任务组中去
this.taskGroup.addTask(this.taskArray[i]);
}
// 执行任务组
taskpool.execute(this.taskGroup).then((res) => {
console.log("taskGroup 被执行完毕======================")
})
}
// 任务组的执行函数
@Concurrent
function taskGroupFunc(value: number) {
taskpool.Task.sendData('通知结果回调===sendData================' + value)
}
输出结果:
串行队列(sequenceRunner)
- 串行队列示例代码:
// 串行队列:
sequenceRunnerTask() {
// 创建任务
for (let i = 0; i < 10; i++) {
this.taskArray.push(new taskpool.Task(sequenceRunnerFunc, i));
this.taskArray[i].onReceiveData((value: string) => {
console.log('value=====================' + value)
})
}
// 执行任务
for (let i = 0; i < this.taskArray.length; i++) {
this.runner.execute(this.taskArray[i]).then(async () => {
if (i === this.taskArray.length - 1) {
console.log("串行线程的任务全部被执行完毕======================")
}
});
}
}
//任务执行函数
@Concurrent
function sequenceRunnerFunc(value: number) {
taskpool.Task.sendData('sequenceRunnerFunc===================' + value)
}
输出函数:
长线程任务(LongTask)
表示长时任务。LongTask继承自Task。
长时任务不设置执行时间上限,长时间运行不会触发超时异常,但不支持在任务组(TaskGroup
)执行和多次执行。
执行长时任务的线程一直存在,知道执行完后调用terminateTask
, 该线程会在空闲时间回收
示例:
// 创建一个场任务
logngTask() {
let longTask = new taskpool.LongTask(longFunc, 10000)
longTask.onReceiveData((value: string) => {
console.log("onReceiveData====================" + value)
taskpool.terminateTask(longTask)
})
// 执行长任务
taskpool.execute(longTask, taskpool.Priority.HIGH).then((res) => {
console.log("execute===================" + JSON.stringify(res))
})
}
// 长任务执行方法
@Concurrent
function longFunc(time: number) {
taskpool.Task.sendData('LongTask message===================START')
// 线程任务可以执行长时间任务
let start = new Date().getTime();
while (new Date().getTime() - start < time) {
continue;
}
taskpool.Task.sendData('LongTask message===================END')
}
输出结果:
周期任务
executePeriodically(period: number, task: Task, priority?: Priority): void
周期执行任务,每隔period
时长执行一次任务。当前执行模式支持设置任务优先级和调用cancel
取消任务周期执行。周期任务不可以是任务组任务和串行队列任务,不可以再次调用执行接口,不可以拥有依赖关系
示例
// 周期任务
periodicTask() {
console.log("START=================" + DateUtil.getFormatDateStr(new Date()))
//创建一个任务
let task = new taskpool.Task(periodicFunc)
task.onReceiveData((value: string) => {
console.log("onReceiveData=================" + value + '====' + DateUtil.getFormatDateStr(new Date()))
})
taskpool.executePeriodically(2000, task, taskpool.Priority.HIGH)
}
// 周期任务执行函数
@Concurrent
function periodicFunc() {
taskpool.Task.sendData("periodic周期任务")
}
输出结果:
注意: 该执行函数 调用之后, 不是立刻执行哈, 需要等待设置的period
值后,才开始执行。
这里只是初步介绍了下TaskPool
的一些常用的使用方式, 如需了解更多,更详细的使用, 可以参考官方文档。