HarmonyOS Worker线程中,如何保存成员对象?

当用Worker创建了一个线程之后,我想在worker里始终持有一个对象,如下:

const workerPort: ThreadWorkerGlobalScope = worker.workerPort;  
  
const testBean: TestBean = new TestBean()  
  
workerPort.onmessage = (e: MessageEvents) => {  
  testBean.count ++;  
})

其中TestBean结构如下:

class TestBean {  
    count: number = 0  
}

结果我发了10个消息,结果发现testBean里的count每次都是0,说明Worker中没有持有这个对象。

想问问老师怎么实现这个需求呢?

HarmonyOS
2024-10-21 12:32:40
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Heiang

可以考虑使用ShareArrayBuffer,关键代码: 主线程中:

const workerInstance = new worker.ThreadWorker("entry/ets/pages/worker1.ets");  
const sab = new SharedArrayBuffer(1024);//创建一个sharedArrayBuffer  
workerInstance.postMessage(sab);//向worker发送消息  
worker中:  
import worker, { MessageEvents, ErrorEvent } from '@ohos.worker';  
// 创建worker线程中与主线程通信的对象  
const workerPort = worker.workerPort  
let  sharedArray:Int32Array|null =null;//定义SharedArrayBuffer的视图,方便读写  
// worker线程接收主线程信息  
workerPort.onmessage = (e: MessageEvents): void => {  
  // data:主线程发送的信息  
  let data: SharedArrayBuffer = e.data;  
  if(!sharedArray){  
    sharedArray = new Int32Array(data)//在主线程接受的共享内存上建立视图  
  }  
  sharedArray[0]++;//数据操作  
  console.log(" test show worker监听到消息worker.ets onmessage",sharedArray[0]);  
}  
// worker线程发生error的回调  
workerPort.onerror = (err: ErrorEvent) => {  
  console.log("worker.ets onerror" + err.message);  
}

sharedArrayBuffer可共享对象可以存储任何类型的数据,文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/serialization-support-types-V5#可共享对象

代码:

主线程:

import { ErrorEvent, MessageEvents, worker } from '@kit.ArkTS';  
const workerInstance = new worker.ThreadWorker("entry/ets/pages/worker1.ets");  
const sab = new SharedArrayBuffer(1024);  
let sharedArray = new Array<Object>(sab)//在主线程的共享内存上建立视图  
@Entry  
@Component  
struct Index {  
  @State message: string = 'Hello World';  
  build() {  
    Row() {  
      Column() {  
        Text(this.message)  
          .fontSize(50)  
          .fontWeight(FontWeight.Bold)  
        Button("向worker发送消息").onClick(()=>{  
          sharedArray[0]=new Object({value:'测试内容'})  
          workerInstance.postMessage(sharedArray);//直接向worker线程发送共享内存的视图  
        })  
      }  
      .width('100%')  
    }  
    .height('100%')  
  }  
}

worker:

import worker, { MessageEvents, ErrorEvent } from '@ohos.worker';  
// 创建worker线程中与主线程通信的对象  
const workerPort = worker.workerPort  
let  sharedArray:Array<Object>|null =null;  
// worker线程接收主线程信息  
workerPort.onmessage = (e: MessageEvents): void => {  
  // data:主线程发送的信息  
  let data: SharedArrayBuffer = e.data;  
  if(!sharedArray){  
    sharedArray = new Array<Object>(data)  
  }  
  console.log("ctest show worker监听到消息worker.ets onmessage",JSON.stringify(sharedArray[0]));//stringify为了输出查看  
}  
  
// worker线程发生error的回调  
workerPort.onerror = (err: ErrorEvent) => {  
  console.log("worker.ets onerror" + err.message);  
}

这个是上面demo的实现参考最后一部分Stage模型配置:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-worker-V5#stage模型

1.worker线程ets:(路径:ets/pages/workers/worker1.ets)

import worker, { MessageEvents, ErrorEvent } from '@ohos.worker';  
// 创建worker线程中与主线程通信的对象  
const workerPort = worker.workerPort  
let sharedArray:Array<Object>|null =null;  
// worker线程接收主线程信息  
workerPort.onmessage = (e: MessageEvents): void => {  
  // data:主线程发送的信息  
  let data: SharedArrayBuffer = e.data;  
  if(!sharedArray){  
    sharedArray = new Array<Object>(data)  
  }  
  console.log("ctest show worker监听到消息worker.ets onmessage",JSON.stringify(sharedArray[0]));  
}  
// worker线程发生error的回调  
workerPort.onerror = (err: ErrorEvent) => {  
  console.log("worker.ets onerror" + err.message);  
}

2. 主线程页面ets:(路径:ets/pages/Index.ets)

import { ErrorEvent, MessageEvents, worker } from '@kit.ArkTS';  
import { socket } from '@kit.NetworkKit';  
const workerInstance = new worker.ThreadWorker("entry/ets/pages/workers/worker1.ets");  
const sab = new SharedArrayBuffer(1024);  
let sharedArray = new Array<Object>(sab)  
@Entry  
@Component  
struct Index {  
  @State message: string = 'Hello World';  
  build() {  
    Row() {  
      Column() {  
        Text(this.message)  
          .fontSize(50)  
          .fontWeight(FontWeight.Bold)  
        Button("向worker发送消息").onClick(()=>{  
          let t:socket.TLSSocket = socket.constructTLSSocketInstance();  
          sharedArray[0] = t;  
          workerInstance.postMessage(sharedArray);  
        })  
      }  
      .width('100%')  
    }  
    .height('100%')  
  }  
}

3. build-profile.json5(路径:ets/build-profile.json5)buildOption下添加:

"buildOption": {  
  "sourceOption": {  
    "workers": [  
    "./src/main/ets/pages/workers/worker1.ets"  
    ]  
  }  
}
分享
微博
QQ
微信
回复
2024-10-21 17:28:08
相关问题
如何Worker开启多级子线程
261浏览 • 1回复 待解决
Worker线程如何销毁?
287浏览 • 1回复 待解决
Worker线程内存如何共享
2207浏览 • 1回复 待解决
如何创建一个worker线程
829浏览 • 1回复 待解决
Worker的宿主线程必须是主线程吗?
337浏览 • 1回复 待解决
通过emitter实现worker线程通讯
875浏览 • 1回复 待解决
Worker和TaskPool的线程数量是否有限制
1818浏览 • 1回复 待解决
worker.ts如何获取context
2027浏览 • 2回复 待解决
Worker线程的使用,有谁知道啊?
917浏览 • 1回复 待解决