HarmonyOS鸿蒙Next中Woker线程测试问题

HarmonyOS鸿蒙Next中Woker线程测试问题 我写了一个worker来处理一些任务,worker的初始化和调用都放在class A里。如果我在UI里实例化A,然后调用A的方法,这个方法会给worker发任务,worker会执行任务并返回结果。有意思的是在UI代码里这么做完全没问题,表现也都符合预期。但是到测试代码里就会超时,测试跑不出来。请问是什么原因?(我的任务都是假的,也就是返回一个字符串,绝不存在任务本身超时的问题)

我起初以为是在测试环境中,worker还没启动完成,主线程这边就发消息了,所以导致worker漏掉了消息(这里存疑,我不清楚消息处理的具体机制,有清楚的大佬可以给讲一下)。于是我在测试代码中手写了一个延时等待,等待五秒之后再调用A的方法给worker发任务,但是结果还是一样,测试卡死了。

再有一个很有意思的发现是,在UI代码中,我在worker文件里打断点,然后用debugger调试,程序一启动立即就停在了worker文件里(说明worker在程序刚启动的时候就加载了?),然后有意思的来了,这个时候worker的创建是还没有完成的,但是我在屏幕上按动一个button,程序马上就跳转到button的onclick方法里了,worker的初始化像是被抛弃了。。。。。然后我的UI程序也不正常了。(前文提过,如果是在UI里调用A的方法去给worker发任务的话是没问题的,现在出问题大概率是因为worker的创建有问题)。

总结一下就是这两个问题,

  1. 为什么测试跑worker会被卡死

  2. worker的创建时机是什么?我使用worker之前需不需要确认worker是否就绪?

源代码比较复杂就不粘上来了,代码里用了一个Map来保存未执行完的任务的resolve方法,接收到worker发的消息之后,调用resolve去主动fullfill 在等待的Promise。


更多关于HarmonyOS鸿蒙Next中Woker线程测试问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

楼主您好,官方有提供完整可运行的Worker代码示例,您可以参考:基于线程池实现多线程任务功能

比对一下跟您目前代码是不是写法有出入,如果还是不能解决,建议您提供一个可复现问题的小Demo便于分析。

更多关于HarmonyOS鸿蒙Next中Woker线程测试问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


还是贴一个简单的demo代码,毕竟每个人业务代码环境不同,很难定位问题!

虽然不知道为啥你的会卡住,但是还是请参考一下下面的代码示例,有助于你查找问题:

// Index.ets
import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS';
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            // 宿主线程中创建Worker对象
            const workerInstance = new worker.ThreadWorker("entry/ets/workers/Worker.ets");
            // 宿主线程向worker线程传递信息
            const buffer = new ArrayBuffer(8);
            workerInstance.postMessage(buffer);
            // 宿主线程接收worker线程信息
            workerInstance.onmessage = (e: MessageEvents): void => {
              // data:worker线程发送的信息
              let data: Int8Array = e.data;
              console.info("main thread data is  " + data);
              // 销毁Worker对象
              workerInstance.terminate();
            }
            // 在调用terminate后,执行onexit
            workerInstance.onexit = (code) => {
              console.info("main thread terminate");
            }
            workerInstance.onAllErrors = (err: ErrorEvent) => {
              console.error("main error message " + err.message);
            }
          })
      }
      .width('100%')
      .height('100%')
    }
  }
}
// Worker.ets
import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS';
// 创建worker线程中与宿主线程通信的对象
const workerPort = worker.workerPort;
// worker线程接收宿主线程信息
workerPort.onmessage = (e: MessageEvents): void => {
  // data:宿主线程发送的信息
  let data: ArrayBuffer = e.data;
  // 往收到的buffer里写入数据
  const view = new Int8Array(data).fill(3);
  // worker线程向宿主线程发送信息
  workerPort.postMessage(view);
}
// worker线程发生error的回调
workerPort.onerror = (err: ErrorEvent) => {
  console.error("worker.ets onerror" + err.message);
}

在模块级entry/build-profile.json5配置文件中添加如下配置:

  "buildOption": {
    "sourceOption": {
      "workers": [
        "./src/main/ets/workers/Worker.ets"
      ]
    }
  }

在HarmonyOS Next中,Worker线程用于后台任务执行,避免阻塞主线程。测试时需通过new worker.ThreadWorker()创建实例,利用onmessagepostMessage进行主线程与Worker间通信。测试应覆盖消息传递、错误处理和线程生命周期管理,确保数据同步与性能稳定。使用DevEco Studio的调试工具验证线程行为,关注资源释放以避免内存泄漏。

在HarmonyOS Next中,Worker线程在测试环境卡死通常与线程生命周期管理有关。测试框架可能未正确处理Worker的异步初始化,导致主线程与Worker线程间的消息传递失败。即使添加延时,若Worker未成功初始化,消息仍无法被接收。

Worker的创建时机是在调用new Worker()时立即启动,但初始化完成前可能无法处理消息。最佳实践是在使用Worker前通过监听'ready'事件(如支持)或首次发送简单消息确认其就绪。在测试中,建议使用await等待Worker返回确认信号,而非固定延时。

在UI调试中遇到的初始化中断问题,可能是由于调试器暂停了Worker线程初始化流程,导致状态不一致。确保Worker脚本加载无误,并避免在初始化过程中进行交互操作。

检查测试代码中是否正确处理了Promise的resolve/reject,避免因未决Promise导致测试超时。简化测试用例,验证基础消息收发是否正常,再逐步添加业务逻辑。

回到顶部