1# Sendable Use Scenarios 2Sendable objects can be passed by reference between concurrent instances. Compared with the serialization mode, the reference transfer mode is more efficient and does not lose the member methods carried in the class. Therefore, Sendable can solve the following problems: 3 4- Transferring a large amount of data (for example, more than 100 KB) across concurrent instances 5 6- Passing a class instance object carrying methods across concurrent instances 7 8## Big data transmission across concurrent instances 9 10The overhead of serialization across concurrent instances increases linearly with the data volume. When a large amount of data is transmitted (100 KB data takes about 1 ms to transmit), the overhead of data copy across concurrent instances is high, adversely affecting the parallelization performance. On the contrary, passing objects by reference improves 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 for data transfer. 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 the data of a large size 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 a class instance object carrying methods across concurrent instances 108 109Methods will be lost during serialization of instance objects. In scenarios where instance methods must be called, use pass-by-reference. If data needs to be parsed during data processing, you can use the [ASON tool](ason-parsing-generation.md) to parse the data. 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 for data transfer. 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 transfer of a class 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