新闻详情

新闻详情

首页 / 资讯中心 / 详情

华为鸿蒙开发高级篇04-多线程与并发:TaskPool/Worker 实战

发布时间:2026/9/16 9:22:52来源:尧图网络
华为鸿蒙开发高级篇04-多线程与并发:TaskPool/Worker 实战
华为鸿蒙开发高级篇04-多线程与并发TaskPool/Worker 实战图片批量压缩案例高级系列第 4 篇 · 案例相册批量压缩工具——一次选择 50 张图压缩、保存、进度展示UI 全程不卡顿。 目标搞清楚 ArkTS 并发模型TaskPool vs Worker掌握耗时任务下放子线程、线程间数据传递与进度回传的完整套路。一、案例背景图片压缩、大文件解析、模型推理这类 CPU 密集任务如果在主线程UI 线程执行结果就是点击后白屏、滑动掉帧、甚至 ANR。正确的做法是UI 线程只负责交互与渲染重活交给并发线程结果回传刷新。ArkTS 提供两套并发方案方案适用特点TaskPool一次性/短任务、可复用线程池自动调度、任务级并发、推荐首选Worker常驻长任务、需要独立生命周期手动创建/销毁、适合后台持续作业图片批量压缩是典型的短任务队列用 TaskPool 最合适文末给 Worker 的对照实现。二、核心原理TaskPool 工作方式主线程 ── execute(任务函数, 参数) ── TaskPool系统线程池 ── onReceiveData(进度) ─── 子线程回调 ── Promise结果 ───────── 任务完成要点任务函数必须是独立函数或独立 Concurrent 函数不能依赖闭包捕获主线程对象。传递的参数和返回值必须可序列化基本类型、数组、普通对象不能传自定义类实例/方法。进度回传用sendData/onReceiveData或直接返回聚合结果分批展示。三、实际开发代码图片批量压缩3.1 并发任务函数Concurrent// concurrency/compressTask.ets import { taskpool } from kit.ArkTS // Concurrent标记为可在线程池执行的函数 // 入参/返回值必须可序列化这里传图片路径 压缩参数 Concurrent function compressOne(arg: CompressArg): CompressResult { const { src, quality, index } arg // 真实场景读取 image source → 解码 → 压缩编码 → 写回文件 // 这里用伪实现模拟耗时与结果替换为实际图像编解码代码即可 const start Date.now() // 模拟压缩耗时 50~120ms while (Date.now() - start 60 (index % 60)) { // busy wait 模拟 CPU 密集 } const outPath src.replace(.jpg, _q${quality}.jpg) return { index, outPath, savedBytes: 1024 * (quality 60 ? 320 : 180) // 模拟压缩后大小 } } export interface CompressArg { src: string quality: number index: number } export interface CompressResult { index: number outPath: string savedBytes: number }3.2 批量调度TaskPool 并发限制 进度// service/CompressService.ets import { taskpool } from kit.ArkTS import { compressOne, CompressArg, CompressResult } from ../concurrency/compressTask export class CompressService { // 一次最多并发 3 个任务避免资源打满 private readonly maxConcurrent 3 // 返回进度回调onProgress(index, total) async compressAll( sources: string[], quality: number, onProgress: (done: number, total: number) void ): PromiseCompressResult[] { const results: CompressResult[] [] let done 0 // 任务队列用 Promise 手动控制并发数简单版信号量 const queue sources.map((src, index) { const arg: CompressArg { src, quality, index } return taskpool.execute(compressOne, arg).then((r) r as CompressResult) }) // 分批 await控制同时执行的个数 for (let i 0; i queue.length; i this.maxConcurrent) { const batch queue.slice(i, i this.maxConcurrent) const batchResults await Promise.all(batch) results.push(...batchResults) done batchResults.length onProgress(done, sources.length) // 进度回传 UI } return results } }说明上述分批 Promise是最易读的并发限制写法追求极致吞吐可改用计数信号量start 一批后立即补充。真实压缩代码请使用kit.ImageKitImagePacker/ImageSource完成解码与编码。3.3 UI 层进度展示 不卡顿// pages/CompressPage.ets import { CompressService } from ../service/CompressService Entry Component struct CompressPage { private service: CompressService new CompressService() // 模拟 50 张图片路径 private sources: string[] Array.from({ length: 50 }, (_, i) /data/img_${i 1}.jpg) State progress: number 0 State totalText: string State running: boolean false private async startCompress() { if (this.running) return this.running true this.progress 0 this.totalText 开始压缩... try { const results await this.service.compressAll(this.sources, 60, (done, total) { // 进度回调更新状态UI 自动刷新主线程空闲滑动依旧流畅 this.progress Math.round((done / total) * 100) this.totalText 已压缩 ${done}/${total} 张 }) this.totalText 完成共 ${results.length} 张本批省下约 ${this.sumBytes(results)} KB } catch (e) { this.totalText 压缩失败${(e as Error).message} } finally { this.running false } } private sumBytes(results: { savedBytes: number }[]): number { return Math.round(results.reduce((s, r) s r.savedBytes, 0) / 1024) } build() { Column({ space: 24 }) { Text(相册批量压缩).fontSize(24).fontWeight(FontWeight.Bold) // 进度环复用第 1 篇的自绘组件思路这里用系统组件 Progress({ value: this.progress, total: 100 }) .width(100%).color(#007DFF) Text(this.totalText).fontSize(14).fontColor(#86909C) Button(this.running ? 压缩中... : 开始压缩 50 张, { type: ButtonType.Capsule }) .width(100%) .enabled(!this.running) .onClick(() this.startCompress()) // 说明压缩期间可以来回拖动这个列表验证 UI 不卡 List() { ForEach(Array.from({ length: 20 }, (_, i) 滑动测试项 ${i 1}), (item: string) { ListItem() { Text(item).fontSize(14).padding(10) } }, (item: string) item) } .layoutWeight(1) .width(100%) } .padding(24) } }3.4 Worker 对照常驻任务场景TaskPool 之外的场景长驻后台、独立生命周期用 Worker// workers/workerDemo.ets —— 子线程入口 import { worker, ThreadWorkerGlobalScope } from kit.ArkTS const workerPort worker.workerPort as ThreadWorkerGlobalScope workerPort.onmessage (e) { const { src, quality } e.data // 执行压缩... const result { src, quality, ok: true } // 回传结果 workerPort.postMessage(result) } workerPort.onmessageerror () { workerPort.close() }// 主线程使用 import { worker } from kit.ArkTS const wk new worker.ThreadWorker(entry/ets/workers/workerDemo.ets) wk.onmessage (e) { /* 接收子线程结果 */ } wk.postMessage({ src: /data/a.jpg, quality: 60 }) // 用完释放 // wk.terminate()选型建议默认 TaskPool自动管理、代码简洁需要长期存活、手动控制生命周期的后台任务才上 Worker。四、优化与踩坑问题处理报taskpool execute 参数不可序列化传基本类型/可序列化对象自定义类实例不能直接传任务函数报 undefined并发函数必须独立定义或 Concurrent不能引用外部闭包变量进度回调不刷新回调里更新State若频率过高可节流如每 5 条一次并发开太大反而变慢压测找最优并发数本例 3~5压缩任务本身也吃 CPU/IOWorker 消息丢失postMessage 是异步的业务侧做好回调幂等异常走 onmessageerror 收尾真机内存暴涨分批处理 及时释放 ImageSource避免一次性解码全部大图五、小结与延伸并发选型短任务队列 → TaskPool长驻后台 → Worker。三要素Concurrent 独立任务函数、可序列化参数、进度回传回调/Promise。案例沉淀CompressService并发受限的批量任务调度器 进度 UI可直接套用于文件转换、批量下载、数据迁移等场景。延伸任务取消检查取消标志、任务优先级、与分布式第 8 篇结合做跨端任务下发。下一篇预告网络层架构实战——统一请求层设计拦截器/缓存/重试/取消新闻客户端案例。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

具身智能技术创新原理(28):一种基于TVA具身架构的自适应推理优化框架 2026/9/16 9:56:01

具身智能技术创新原理(28):一种基于TVA具身架构的自适应推理优化框架

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”或“TVA视觉智能体”)是依托Transformer架构与“因式智能体”理论构建的通用视觉技术体系。它有机融合深度强化学习(DRL)、卷积…

阅读更多 →
智能Agent在技术内容生成中的Prompt工程实践 2026/9/16 9:56:01

智能Agent在技术内容生成中的Prompt工程实践

1. 项目背景与核心价值在内容平台运营领域,如何高效生产优质技术内容一直是个痛点问题。传统人工创作模式存在效率瓶颈,而简单的内容搬运又难以保证质量。这个项目正是要解决这个矛盾——通过构建智能Agent自动化完成从选题策划到内容生成的全流程。我最…

阅读更多 →
全屋定制环保检测解析:气候箱法、CMA报告核验与室内甲醛叠加 2026/9/16 9:56:01

全屋定制环保检测解析:气候箱法、CMA报告核验与室内甲醛叠加

买全屋定制,"环保"被说得最多,也最容易被糊弄。板材等级怎么测?报告怎么核验?单板达标等于全屋达标吗?像欧派这类连锁门店,环保等级可查、检测报告可调,但报告怎么核验、单板达标是否…

阅读更多 →
MSO算法:无人机路径规划的光学折射优化方法 2026/9/16 9:56:01

MSO算法:无人机路径规划的光学折射优化方法

1. 项目背景与核心价值无人机路径规划一直是自动化领域的热点问题。2025年即将发布的算法海市蜃楼算法(Mirage Search Optimization,简称MSO)为这一领域带来了全新的解决思路。这个算法灵感来源于沙漠中光线折射形成的海市蜃楼现象,通过模拟这种自然光学…

阅读更多 →
AI Agent技能抽象层设计:TypeScript契约驱动的可插拔能力架构 2026/9/16 9:56:01

AI Agent技能抽象层设计:TypeScript契约驱动的可插拔能力架构

1. “agent-skills”不是库名,而是能力抽象层的设计范式你第一次在Nx工作区里看到agent-skills这个包名时,大概率会下意识去 npm search —— 结果当然是空的。它不托管在 npm 上,没有 GitHub star 数,也没有 README.md 里的“Ins…

阅读更多 →
INA282电流检测电路设计:从分流电阻到PCB实战 2026/9/16 9:53:00

INA282电流检测电路设计:从分流电阻到PCB实战

简介:ina282.rar 是一份面向硬件工程师的 INA282 高精度电流检测资料包,涵盖芯片特性、工作原理、参考电路及应用,适合电源管理、电池监测等电流测量设计。包内共 43 个文件,以 Altium Designer 工程为主,含原理图&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞