开源 Arkts 鸿蒙应用 开发(十四)线程--任务池(taskpool)

发布于:2025-08-02 ⋅ 阅读:(14) ⋅ 点赞:(0)

 文章的目的为了记录使用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和任务3
  async 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和任务3
  async 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)
  }

  @Builder
  buildResultDisplay() {
    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收到事件后的打印


网站公告

今日签到

点亮在社区的每一天
去签到