开源 Arkts 鸿蒙应用 开发(十四)线程--任务池(taskpool)
文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
开源 Arkts 鸿蒙应用 开发(一)工程文件分析-CSDN博客
开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用-CSDN博客
开源 Arkts 鸿蒙应用 开发(三)Arkts的介绍-CSDN博客
开源 Arkts 鸿蒙应用 开发(四)布局和常用控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(六)数据持久--文件和首选项存储-CSDN博客
开源 Arkts 鸿蒙应用 开发(七)数据持久--sqlite关系数据库-CSDN博客
开源 Arkts 鸿蒙应用 开发(八)多媒体--相册和相机-CSDN博客
开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端-CSDN博客
开源 Arkts 鸿蒙应用 开发(十)通讯--Http-CSDN博客
开源 Arkts 鸿蒙应用 开发(十一)证书和包名修改-CSDN博客
开源 Arkts 鸿蒙应用 开发(十二)传感器的使用-CSDN博客
推荐链接:
开源 java android app 开发(一)开发环境的搭建-CSDN博客
开源 java android app 开发(二)工程文件结构-CSDN博客
开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客
开源 java android app 开发(四)GUI界面重要组件-CSDN博客
开源 java android app 开发(五)文件和数据库存储-CSDN博客
开源 java android app 开发(六)多媒体使用-CSDN博客
开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客
开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客
开源 java android app 开发(九)后台之线程和服务-CSDN博客
开源 java android app 开发(十)广播机制-CSDN博客
开源 java android app 开发(十一)调试、发布-CSDN博客
开源 java android app 开发(十二)封库.aar-CSDN博客
推荐链接:
开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客
开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客
开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客
开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客
开源 Arkts 鸿蒙应用 开发(十)通讯--Http数据传输-CSDN博客开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客
本章内容主要演示了如何使用任务池(taskpool)执行并发任务,以及如何在任务之间通过事件发射器(emitter)进行通信。
1.TaskPool简介
2.源码解析
3.所有源码
4.延时效果
一、TaskPool简介
TaskPool为应用程序提供多线程环境,降低资源消耗并提高系统性能。无需管理线程生命周期。
1.1 运作机制示意图
1.2 TaskPool注意事项
实现任务的函数需要使用@Concurrent装饰器标注
@Concurrent
function printArrayBuffer(buffer: ArrayBuffer) {return buffer;
}
二、源码解析
主要演示了如何使用任务池(taskpool)执行并发任务,以及如何在任务之间通过事件发射器(emitter)进行通信。
2.1 实现@Concurrent方法
// 3. 并发任务函数(仅使用局部变量和参数)
@Concurrent
function task1Function(iterations: number): void {// 使用局部变量存储中间结果let step: number;let calcResult: number;let progress: number;let result = 0;// 1. 首先将复杂计算函数定义为模块级函数for (step = 1; step <= iterations; step++) {// 调用模块级函数进行计算//calcResult = performComplexCalculation(step);for (let i = 0; i < 100000; i++) {result += Math.sin(step) * Math.cos(i);}progress = (step / iterations) * 100;emitter.emit("progress_update", {data: {step,totalSteps: iterations,result: result,progress} as ProgressData});}
}
2.2 taskpool创建和运行
// 按钮2 - 启动任务2和任务3async myClick2() {if (this.task2Running || this.task3Running) return;this.task2Running = true;this.task3Running = true;this.message = "启动任务2和任务3";this.task2 = new taskpool.Task(task2Function);this.task3 = new taskpool.Task(task3Function);await taskpool.execute(this.task2);await taskpool.execute(this.task3);console.info("任务2和任务3已启动");}
2.3 使用Emitter进行线程间通信
Emitter用于同一进程内相同线程或不同线程间的事件处理,事件异步执行。使用时需要先订阅一个事件,然后发布该事件,发布完成后Emitter会将已发布的事件分发给订阅者,订阅者就会执行该事件订阅时设置的回调方法。当不需要订阅该事件时应及时取消订阅释放Emitter资源。
任务3订阅消息
@Concurrent
function task3Function(): void {console.info("任务3正在运行,等待接收消息");emitter.on("task2_to_task3", (data) => {console.info("任务3收到消息: " + JSON.stringify(data));});
}
按钮3发送消息
// 按钮3 - 从任务2向任务3发送消息myClick3() {if (!this.task2Running || !this.task3Running) {this.message = "请先启动任务2和任务3";return;}emitter.emit("task2_to_task3", {data: {message: "这是来自任务2的消息",timestamp: new Date().getTime()}});this.message1 = "已从任务2向任务3发送消息";}
任务1每次进行复杂运算后,将进度条的值通过Emitter发送给主线程
@Concurrent
function task1Function(iterations: number): void {// 使用局部变量存储中间结果let step: number;let calcResult: number;let progress: number;let result = 0;// 1. 首先将复杂计算函数定义为模块级函数for (step = 1; step <= iterations; step++) {// 调用模块级函数进行计算//calcResult = performComplexCalculation(step);for (let i = 0; i < 100000; i++) {result += Math.sin(step) * Math.cos(i);}progress = (step / iterations) * 100;emitter.emit("progress_update", {data: {step,totalSteps: iterations,result: result,progress} as ProgressData});}
}
三、所有代码,不要权限配置,只有一个文件Index.ets
3.1 主要功能模块
1) 并发任务执行 (complexCalculationTask)
这是一个计算密集型任务,模拟复杂计算过程
使用@Concurrent装饰器标记,表示可以在任务池中并发执行
计算过程中通过emitter.emit()发送进度更新事件
包含嵌套循环计算正弦和余弦值并累加结果
2.)任务间通信 (task2Function 和 task3Function)
两个简单的并发任务,演示任务间通信
任务3监听"task2_to_task3"事件
任务2通过按钮触发向任务3发送消息
3) UI组件 (Index组件)
显示计算进度和结果
3.2 源码Index.ets
// index.ets
import taskpool from '@ohos.taskpool';
import { BusinessError } from '@ohos.base';
import emitter from '@ohos.events.emitter';interface ProgressEvent {data: ProgressData;
}
// 2. 定义进度数据类型
interface ProgressData {step: number;totalSteps: number;result: number;progress: number;
}// 3. 并发任务函数(仅使用局部变量和参数)
@Concurrent
function task1Function(iterations: number): void {// 使用局部变量存储中间结果let step: number;let calcResult: number;let progress: number;let result = 0;// 1. 首先将复杂计算函数定义为模块级函数for (step = 1; step <= iterations; step++) {// 调用模块级函数进行计算//calcResult = performComplexCalculation(step);for (let i = 0; i < 100000; i++) {result += Math.sin(step) * Math.cos(i);}progress = (step / iterations) * 100;emitter.emit("progress_update", {data: {step,totalSteps: iterations,result: result,progress} as ProgressData});}
}@Concurrent
function task2Function(): void {console.info("任务2正在运行");// 任务2将在按下按钮3时向任务3发送消息
}@Concurrent
function task3Function(): void {console.info("任务3正在运行,等待接收消息");emitter.on("task2_to_task3", (data) => {console.info("任务3收到消息: " + JSON.stringify(data));});
}@Entry
@Component
struct Index {@State message: string = "准备执行复杂计算";@State message1: string = "准备执行复杂计算";@State progress: number = 0;@State currentStep: number = 0;@State results: number[] = [];private taskRunning: boolean = false;private task2Running: boolean = false;private task3Running: boolean = false;private task2: taskpool.Task | null = null;private task3: taskpool.Task | null = null;aboutToDisappear() {emitter.off("progress_update");}async task1() {if (this.taskRunning) return;this.taskRunning = true;this.resetState();emitter.on("progress_update", (eventData: ProgressEvent) => {this.updateProgress(eventData.data);});try {const task = new taskpool.Task(task1Function, 10);await taskpool.execute(task);this.message = "计算完成!";} catch (error) {this.handleError(error as BusinessError);} finally {this.cleanup();}}private resetState(): void {this.message = "计算进行中...";this.progress = 0;this.currentStep = 0;this.results = [];}private updateProgress(data: ProgressData): void {this.currentStep = data.step;this.progress = data.progress;this.results = [...this.results, data.result];this.message = `计算进度: ${this.currentStep}/20`;}private handleError(error: BusinessError): void {this.message = `计算错误: ${error.message}`;console.error("Task failed:", error);}private cleanup(): void {this.taskRunning = false;emitter.off("progress_update");}// 按钮2 - 启动任务2和任务3async myClick2() {if (this.task2Running || this.task3Running) return;this.task2Running = true;this.task3Running = true;this.message = "启动任务2和任务3";this.task2 = new taskpool.Task(task2Function);this.task3 = new taskpool.Task(task3Function);await taskpool.execute(this.task2);await taskpool.execute(this.task3);console.info("任务2和任务3已启动");}// 按钮3 - 从任务2向任务3发送消息myClick3() {if (!this.task2Running || !this.task3Running) {this.message = "请先启动任务2和任务3";return;}emitter.emit("task2_to_task3", {data: {message: "这是来自任务2的消息",timestamp: new Date().getTime()}});this.message1 = "已从任务2向任务3发送消息";}build() {Column() {Text(this.message).fontSize(20).margin(10);Progress({value: this.progress,total: 100,style: ProgressStyle.Linear}).width('90%').height(30).margin(10);this.buildResultDisplay()Column() {Text(this.message1).fontSize(20).margin(10);Button('启动任务2 - 创建任务2和任务3').width('80%').height(60).margin(10).onClick(() => this.myClick2());Button('启动任务3 - 发送数据').width('80%').height(60).margin(10).onClick(() => this.myClick3());}}.width('100%').height('100%').padding(10)}@BuilderbuildResultDisplay() {Column() {Text(`当前步骤: ${this.currentStep}/20`).fontSize(16).margin(5);Text(`最新结果: ${this.results[this.results.length - 1]?.toFixed(4) || '无'}`).fontSize(16).margin(5);Button('开始复杂计算').width('80%').height(60).margin(10).onClick(() => this.task1());}}
}
四、演示效果
手机效果图片
任务2、3启动打印和任务3收到事件后的打印