• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Use Scenarios of Sendable
2Sendable objects can be passed by reference between concurrent instances. This approach is more efficient than serialization and preserves methods carried in class instances. As a result, Sendable is particularly useful in two scenarios:
3
4- Transmitting a large amount of data (for example, data exceeding 100 KB) across concurrent instances
5
6- Passing class instances carrying methods across concurrent instances
7
8## Transmitting Large Data Across Concurrent Instances
9
10Serialization overhead increases linearly with the amount of data. When transmitting large data volumes (100 KB taking approximately 1 ms), the copying overhead can significantly impact application performance. On the contrary, passing objects by reference can greatly enhance performance.
11
12**Example**
13
14```ts
15// Index.ets
16import { taskpool } from '@kit.ArkTS';
17import { testTypeA, testTypeB, Test } from './sendable';
18import { BusinessError, emitter } from '@kit.BasicServicesKit';
19
20// Simulate data processing in a concurrent function.
21@Concurrent
22async function taskFunc(obj: Test) {
23  console.info("test task res1 is: " + obj.data1.name + " res2 is: " + obj.data2.name);
24}
25
26async function test() {
27  // Use TaskPool to pass data.
28  let a: testTypeA = new testTypeA("testTypeA");
29  let b: testTypeB = new testTypeB("testTypeB");
30  let obj: Test = new Test(a, b);
31  let task: taskpool.Task = new taskpool.Task(taskFunc, obj);
32  await taskpool.execute(task);
33}
34
35@Concurrent
36function SensorListener() {
37  // Listening logic
38  // ...
39}
40
41@Entry
42@Component
43struct Index {
44  build() {
45    Column() {
46      Text("Listener task")
47        .id('HelloWorld')
48        .fontSize(50)
49        .fontWeight(FontWeight.Bold)
50        .onClick(() => {
51          let sensorTask = new taskpool.LongTask(SensorListener);
52          emitter.on({ eventId: 0 }, (data) => {
53            // Do something here
54            console.info(`Receive ACCELEROMETER data: {${data.data?.x}, ${data.data?.y}, ${data.data?.z}`);
55          });
56          taskpool.execute(sensorTask).then(() => {
57            console.info("Add listener of ACCELEROMETER success");
58          }).catch((e: BusinessError) => {
59            // Process error
60          })
61        })
62      Text("Data processing task")
63        .id('HelloWorld')
64        .fontSize(50)
65        .fontWeight(FontWeight.Bold)
66        .onClick(() => {
67          test();
68        })
69    }
70    .height('100%')
71    .width('100%')
72  }
73}
74```
75
76```ts
77// sendable.ets
78// Assemble large data in a Sendable class.
79@Sendable
80export class testTypeA {
81  name: string = "A";
82  constructor(name: string) {
83    this.name = name;
84  }
85}
86
87@Sendable
88export class testTypeB {
89  name: string = "B";
90  constructor(name: string) {
91    this.name = name;
92  }
93}
94
95@Sendable
96export class Test {
97  data1: testTypeA;
98  data2: testTypeB;
99  constructor(arg1: testTypeA, arg2: testTypeB) {
100    this.data1 = arg1;
101    this.data2 = arg2;
102  }
103}
104```
105
106
107## Passing Class Instances Carrying Methods Across Concurrent Instances
108
109Methods are lost during serialization of instance objects. Therefore, in scenarios where instance methods must be called, passing objects by reference is essential. If data parsing is required during processing, the [ASON utility](ason-parsing-generation.md) can be used for data parsing.
110
111
112**Example**
113
114```ts
115// Index.ets
116import { taskpool, ArkTSUtils } from '@kit.ArkTS';
117import { SendableTestClass, ISendable } from './sendable';
118
119// Simulate data processing in a concurrent function.
120@Concurrent
121async function taskFunc(sendableObj: SendableTestClass) {
122  console.info("SendableTestClass: name is: " + sendableObj.printName() + ", age is: " + sendableObj.printAge() + ", sex is: " + sendableObj.printSex());
123  sendableObj.setAge(28);
124  console.info("SendableTestClass: age is: " + sendableObj.printAge());
125
126  // Parse the sendableObj.arr data to generate a JSON string.
127  let str = ArkTSUtils.ASON.stringify(sendableObj.arr);
128  console.info("SendableTestClass: str is: " + str);
129
130  // Parse the data and generate ISendable data.
131  let jsonStr = '{"name": "Alexa", "age": 23, "sex": "female"}';
132  let obj = ArkTSUtils.ASON.parse(jsonStr) as ISendable;
133  console.info("SendableTestClass: type is: " + typeof obj);
134  console.info("SendableTestClass: name is: " + (obj as object)?.["name"]); // Output: 'Alexa'
135  console.info("SendableTestClass: age is: " + (obj as object)?.["age"]); // Output: 23
136  console.info("SendableTestClass: sex is: " + (obj as object)?.["sex"]); // Output: 'female'
137}
138async function test() {
139  // Use TaskPool to pass data.
140  let obj: SendableTestClass = new SendableTestClass();
141  let task: taskpool.Task = new taskpool.Task(taskFunc, obj);
142  await taskpool.execute(task);
143}
144
145@Entry
146@Component
147struct Index {
148  @State message: string = 'Hello World';
149
150  build() {
151    RelativeContainer() {
152      Text(this.message)
153        .id('HelloWorld')
154        .fontSize(50)
155        .fontWeight(FontWeight.Bold)
156        .alignRules({
157          center: { anchor: '__container__', align: VerticalAlign.Center },
158          middle: { anchor: '__container__', align: HorizontalAlign.Center }
159        })
160        .onClick(() => {
161          test();
162        })
163    }
164    .height('100%')
165    .width('100%')
166  }
167}
168```
169
170```ts
171// sendable.ets
172// Define a Test class to simulate the operation of passing a class instance carrying methods.
173import { lang, collections } from '@kit.ArkTS'
174
175export type ISendable = lang.ISendable;
176
177@Sendable
178export class SendableTestClass {
179  name: string = 'John';
180  age: number = 20;
181  sex: string = "man";
182  arr: collections.Array<number> = new collections.Array<number>(1, 2, 3);
183  constructor() {
184  }
185  setAge(age: number) : void {
186    this.age = age;
187  }
188
189  printName(): string {
190    return this.name;
191  }
192
193  printAge(): number {
194    return this.age;
195  }
196
197  printSex(): string {
198    return this.sex;
199  }
200}
201```
202