当前位置: 首页 > news >正文

开源 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收到事件后的打印

http://www.dtcms.com/a/310156.html

相关文章:

  • 什么类型网站适合WEB应用防火墙?
  • (27)运动目标检测之对二维点集进行卡尔曼滤波
  • 全国青少年信息素养大赛(无人飞行器主题赛(星际迷航)游记)
  • plc 以太网通讯模块实现:施耐德 PLC 多设备实时数据无缝协同应用案例
  • Java Validator自定义日期范围验证注解:实现不超过一年的时间跨度校验
  • 面向对象三大特性---封装
  • FileInputStream 和 FileOutputStream 简介
  • ubuntu22.04系统入门 linux入门(二) 简单命令 多实践以及相关文件管理命令
  • 便携式综合气象观测仪:随时随地 “捕捉” 天气变化
  • PaddleOcr转onnx和推理
  • python:前馈人工神经网络算法之实战篇,以示例带学,弄明白神经网络算法应用的思路、方法与注意事项等
  • 高斯透镜公式(调整镜头与感光元件之间的距离时,使得不同距离的物体在感光元件上形成清晰的影像)
  • 企业级LLM智能引擎 的完整解决方案,整合了 SpringAI框架、RAG技术、模型控制平台(MCP)和实时搜索,提供从架构设计到代码实现的全面指南:
  • 【iOS】retain/release底层实现原理
  • Java 日期时间格式化模式说明
  • PTE之路--01
  • vivado扫盲 out-of-context(腾讯元宝)
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现围栏羊驼的检测识别(C#代码,UI界面版)
  • Android Material Components 全面解析:打造现代化 Material Design 应用
  • 数据处理四件套:NumPy/Pandas/Matplotlib/Seaborn速通指南
  • 如何在不依赖 Office 的情况下转换 PDF 为可编辑文档
  • lesson30:Python迭代三剑客:可迭代对象、迭代器与生成器深度解析
  • Redis 数据结构全景解析
  • Linux内核构建系统中的auto.conf与autoconf.h:原理与作用解析
  • 3D 管道如何实现流动的?
  • 基于SpringBoot+MyBatis+MySQL+VUE实现的疗养院管理系统(附源码+数据库+毕业论文+远程部署)
  • cesium FBO(三)渲染到Canvas(灰度图效果)
  • 【OneAPI】网页搜索API和网页正文提取API
  • Lombok常用注解及功能详解
  • oracle的安全加密有哪些?