1e41f4b71Sopenharmony_ci# Sendable Development
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Basic Concepts
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci### Sendable Protocol
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciThe Sendable protocol defines the sendable object system and its specifications of ArkTS. Data that complies with the Sendable protocol (referred to as [sendable data](#sendable-data-types)) can be passed between ArkTS concurrent instances.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciBy default, sendable data is passed by reference between ArkTS concurrent instances (including the main thread and the worker thread of TaskPool or Worker) and is allocated in the shared heap. Pass-by-copy is also supported. Non-sendable data is allocated in the local heap, which is private.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ciData races may occur when multiple concurrent instances attempt to update mutable sendable data at the same time. To address this issue, ArkTS introduces the asynchronous lock.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci**Figure 1** Sendable data and shared heap
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci![Sendable](figures/sendable.png)
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci**Figure 2** Pass-by-copy of serialized data
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci![Serialize](figures/serialize.png)
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci**Example**
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci```ts
24e41f4b71Sopenharmony_ciimport { taskpool, worker } from '@kit.ArkTS';
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci@Sendable
27e41f4b71Sopenharmony_ciclass A {}
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_cilet a: A = new A();
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci@Concurrent
32e41f4b71Sopenharmony_cifunction foo(a: A) {}
33e41f4b71Sopenharmony_cilet task: taskpool.Task = new taskpool.Task(foo, a)
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_cilet w = new worker.ThreadWorker("entry/ets/workers/Worker.ets")
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci// 1. Implementation of TaskPool pass-by-sharing
38e41f4b71Sopenharmony_citaskpool.execute(task).then(() => {})
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci// 2. Implementation of Worker pass-by-sharing
41e41f4b71Sopenharmony_ciw.postMessageWithSharedSendable(a)
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci// 3. Implementation of TaskPool pass-by-copy
44e41f4b71Sopenharmony_citask.setCloneList([a])
45e41f4b71Sopenharmony_citaskpool.execute(task).then(() => {})
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci// 4. Implementation of Worker pass-by-copy
48e41f4b71Sopenharmony_ciw.postMessage(a)
49e41f4b71Sopenharmony_ci```
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci### Sendable Class
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci> **NOTE**
55e41f4b71Sopenharmony_ci>
56e41f4b71Sopenharmony_ci> Since API version 11, the @Sendable decorator can be used to verify the sendable class.
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ciA sendable class must meet the following requirements:
59e41f4b71Sopenharmony_ci1. Be marked by and only by the [@Sendable decorator](#sendable-decorator-declaring-and-verifying-a-sendable-class).
60e41f4b71Sopenharmony_ci2. Meet the [sendable usage rules](#sendable-usage-rules).
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci### Sendable Function
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ci> **NOTE**
65e41f4b71Sopenharmony_ci>
66e41f4b71Sopenharmony_ci> Since API version 12, the @Sendable decorator can be used to verify the sendable function.
67e41f4b71Sopenharmony_ci>
68e41f4b71Sopenharmony_ci> To use a sendable function in API version 12, you must configure "compatibleSdkVersionStage": "beta3" in the project. Otherwise, the function does not take effect. For details, see [build-profile.json5](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-profile-V5).
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ciA sendable function must meet the following requirements:
71e41f4b71Sopenharmony_ci1. Be marked by and only by the [@Sendable decorator](#sendable-decorator-declaring-and-verifying-a-sendable-function).
72e41f4b71Sopenharmony_ci2. Meet the [sendable usage rules](#sendable-usage-rules).
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci### Sendable Interface
75e41f4b71Sopenharmony_ciA sendable interface must meet the following requirements:
76e41f4b71Sopenharmony_ci1. Be [ISendable](#isendable) or inherit from [ISendable](#isendable).
77e41f4b71Sopenharmony_ci2. Meet the [sendable usage rules](#sendable-usage-rules).
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci### Sendable Data Types
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci- All basic ArkTS data types: boolean, number, string, bigint, null, and undefined.
83e41f4b71Sopenharmony_ci- Container type defined in the ArkTS common library. In this case, [@arkts.collections](../reference/apis-arkts/js-apis-arkts-collections.md) must be explicitly imported.
84e41f4b71Sopenharmony_ci- **AsyncLock** object defined in the ArkTS common library. In this case, [@arkts.utils](../reference/apis-arkts/js-apis-arkts-utils.md) must be explicitly imported.
85e41f4b71Sopenharmony_ci- Interfaces that inherit [ISendable](#isendable).
86e41f4b71Sopenharmony_ci- Class marked with the [@Sendable decorator](#sendable-decorator-declaring-and-verifying-a-sendable-class).
87e41f4b71Sopenharmony_ci- Function marked with the [@Sendable decorator](#sendable-decorator-declaring-and-verifying-a-sendable-function).
88e41f4b71Sopenharmony_ci- System objects that have accessed the Sendable class. For details, see [Sendable System Objects](arkts-sendable-system-object-list.md).
89e41f4b71Sopenharmony_ci- Elements whose union type data is of the sendable type.
90e41f4b71Sopenharmony_ci
91e41f4b71Sopenharmony_ci> **NOTE**
92e41f4b71Sopenharmony_ci>
93e41f4b71Sopenharmony_ci> - JS built-in objects are passed between concurrent instances in compliance with the structured clone algorithm, and the semantics is passed by copy. Therefore, the instance of a JS built-in object is not of the sendable type.
94e41f4b71Sopenharmony_ci>
95e41f4b71Sopenharmony_ci> - Object literals and array literals are passed between concurrent instances in compliance with the structured clone algorithm, and the semantics is passed by copy. Therefore, object literals and array literals are not of the sendable type.
96e41f4b71Sopenharmony_ci>
97e41f4b71Sopenharmony_ci> - For details about the behavior differences between ArkTS collections APIs and native APIs, see [Behavior Differences](arkts-collections-vs-native-api-comparison.md).
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci### ISendable
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ciThe interface **ISendable {}** is introduced to the ArkTS common library [@arkts.lang](../reference/apis-arkts/js-apis-arkts-lang.md) without any necessary method or property. **ISendable** is the parent type of all sendable types except null and undefined. **ISendable** is mainly used when you want to customize the sendable data struct. The class decorator [@Sendable](#sendable-decorator-declaring-and-verifying-a-sendable-class) is the syntax sugar for implementing **ISendable**.
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci##  \@Sendable Decorator: Declaring and Verifying a Sendable Class
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci### Decorator Description
108e41f4b71Sopenharmony_ci| \@Sendable Decorator        | Description                                                                  |
109e41f4b71Sopenharmony_ci| ------------------------- | ---------------------------------------------------------------------- |
110e41f4b71Sopenharmony_ci| Decorator parameters                | None.                                                                  |
111e41f4b71Sopenharmony_ci| Use scenario restrictions              | The decorator can be used only in projects of the stage model. It can be used only in .ets files.                   |
112e41f4b71Sopenharmony_ci| Inheritance relationship restrictions for decorated classes       | A sendable class can inherit only from another sendable class. A common class cannot inherit from a sendable class. |
113e41f4b71Sopenharmony_ci| Property type restrictions for decorated objects | 1. The following types are supported: string, number, boolean, bigint, null, undefined, Sendable class, collections.Array, collections.Map, and collections.Set.<br>2. Closure variables are not allowed.<br>3. Private properties must be defined using **private**, rather than the number sign (#).<br>4. Computed properties are not supported.          |
114e41f4b71Sopenharmony_ci| Other property restrictions for decorated objects| Member properties must be explicitly declared and initialized. They cannot be followed by exclamation marks (!).|
115e41f4b71Sopenharmony_ci| Method parameters restrictions for decorated objects | Local variables, input parameters, and variables imported through **import** are supported. Closure variables are not allowed.          |
116e41f4b71Sopenharmony_ci| Sendable class restrictions     | Properties cannot be added or deleted, but can be modified. The property types before and after the modification must be the same. Methods cannot be modified.  |
117e41f4b71Sopenharmony_ci| Use scenario                 | 1. The class methods can be used in TaskPool or Worker.<br>2. The sendable type is used when a large amount of data needs to be transmitted.        |
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ci### Decorator Example
121e41f4b71Sopenharmony_ci
122e41f4b71Sopenharmony_ci```ts
123e41f4b71Sopenharmony_ci@Sendable
124e41f4b71Sopenharmony_ciclass SendableTestClass {
125e41f4b71Sopenharmony_ci  desc: string = "sendable: this is SendableTestClass ";
126e41f4b71Sopenharmony_ci  num: number = 5;
127e41f4b71Sopenharmony_ci  printName() {
128e41f4b71Sopenharmony_ci    console.info("sendable: SendableTestClass desc is: " + this.desc);
129e41f4b71Sopenharmony_ci  }
130e41f4b71Sopenharmony_ci  get getNum(): number {
131e41f4b71Sopenharmony_ci    return this.num;
132e41f4b71Sopenharmony_ci  }
133e41f4b71Sopenharmony_ci}
134e41f4b71Sopenharmony_ci```
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci##  \@Sendable Decorator: Declaring and Verifying a Sendable Function
137e41f4b71Sopenharmony_ci
138e41f4b71Sopenharmony_ci### Decorator Description
139e41f4b71Sopenharmony_ci| \@Sendable Decorator        | Description                                                                  |
140e41f4b71Sopenharmony_ci| ------------------------- | ---------------------------------------------------------------------- |
141e41f4b71Sopenharmony_ci| Decorator parameters                | None.                                                                  |
142e41f4b71Sopenharmony_ci| Use scenario restrictions              | The decorator can be used only in projects of the stage model. It can be used only in .ets files.                   |
143e41f4b71Sopenharmony_ci| Restrictions for decorated function types         | Only common functions and async functions can be decorated by @Sendable. |
144e41f4b71Sopenharmony_ci| Restrictions for the decorated function body           | Do not use closure variables, except the sendable class and sendable function defined at the top layer.|
145e41f4b71Sopenharmony_ci| Sendable function restrictions   | Properties cannot be added, deleted, or modified.  |
146e41f4b71Sopenharmony_ci| Use scenario                 | 1. The sendable function can be used in TaskPool or Worker.<br>2. The sendable type is used when a large amount of data needs to be transmitted.|
147e41f4b71Sopenharmony_ci
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci### Decorator Example
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ci```ts
152e41f4b71Sopenharmony_ci@Sendable
153e41f4b71Sopenharmony_citype SendableFuncType = () => void;
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci@Sendable
156e41f4b71Sopenharmony_ciclass TopLevelSendableClass {
157e41f4b71Sopenharmony_ci  num: number = 1;
158e41f4b71Sopenharmony_ci  PrintNum() {
159e41f4b71Sopenharmony_ci    console.info("Top level sendable class");
160e41f4b71Sopenharmony_ci  }
161e41f4b71Sopenharmony_ci}
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ci@Sendable
164e41f4b71Sopenharmony_cifunction TopLevelSendableFunction() {
165e41f4b71Sopenharmony_ci  console.info("Top level sendable function");
166e41f4b71Sopenharmony_ci}
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci@Sendable
169e41f4b71Sopenharmony_cifunction SendableTestFunction() {
170e41f4b71Sopenharmony_ci  const topClass = new TopLevelSendableClass (); // Top-level sendable class.
171e41f4b71Sopenharmony_ci  topClass.PrintNum();
172e41f4b71Sopenharmony_ci  TopLevelSendableFunction (); // Top-level sendable function.
173e41f4b71Sopenharmony_ci  console.info("Sendable test function");
174e41f4b71Sopenharmony_ci}
175e41f4b71Sopenharmony_ci
176e41f4b71Sopenharmony_ci@Sendable
177e41f4b71Sopenharmony_ciclass SendableTestClass {
178e41f4b71Sopenharmony_ci  constructor(func: SendableFuncType) {
179e41f4b71Sopenharmony_ci    this.callback = func;
180e41f4b71Sopenharmony_ci  }
181e41f4b71Sopenharmony_ci  callback: SendableFuncType; // Top-level sendable function.
182e41f4b71Sopenharmony_ci
183e41f4b71Sopenharmony_ci  CallSendableFunc() {
184e41f4b71Sopenharmony_ci    SendableTestFunction (); // Top-level sendable function.
185e41f4b71Sopenharmony_ci  }
186e41f4b71Sopenharmony_ci}
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_cilet sendableClass = new SendableTestClass(SendableTestFunction);
189e41f4b71Sopenharmony_cisendableClass.callback();
190e41f4b71Sopenharmony_cisendableClass.CallSendableFunc();
191e41f4b71Sopenharmony_ci```
192e41f4b71Sopenharmony_ci
193e41f4b71Sopenharmony_ci## Sendable Usage Rules
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ci### 1. A sendable class can inherit only from another sendable class.
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ci> **NOTE**
198e41f4b71Sopenharmony_ci>
199e41f4b71Sopenharmony_ci> The class here does not include variables. In other words, a sendable class cannot inherit from a variable.
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ci**Positive example:**
202e41f4b71Sopenharmony_ci```ts
203e41f4b71Sopenharmony_ci@Sendable
204e41f4b71Sopenharmony_ciclass A {
205e41f4b71Sopenharmony_ci  constructor() {
206e41f4b71Sopenharmony_ci  }
207e41f4b71Sopenharmony_ci}
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ci@Sendable
210e41f4b71Sopenharmony_ciclass B extends A {
211e41f4b71Sopenharmony_ci  constructor() {
212e41f4b71Sopenharmony_ci    super()
213e41f4b71Sopenharmony_ci  }
214e41f4b71Sopenharmony_ci}
215e41f4b71Sopenharmony_ci```
216e41f4b71Sopenharmony_ci
217e41f4b71Sopenharmony_ci**Negative example:**
218e41f4b71Sopenharmony_ci```ts
219e41f4b71Sopenharmony_ciclass A {
220e41f4b71Sopenharmony_ci  constructor() {
221e41f4b71Sopenharmony_ci  }
222e41f4b71Sopenharmony_ci}
223e41f4b71Sopenharmony_ci
224e41f4b71Sopenharmony_ci@Sendable
225e41f4b71Sopenharmony_ciclass B extends A {
226e41f4b71Sopenharmony_ci  constructor() {
227e41f4b71Sopenharmony_ci    super()
228e41f4b71Sopenharmony_ci  }
229e41f4b71Sopenharmony_ci}
230e41f4b71Sopenharmony_ci```
231e41f4b71Sopenharmony_ci
232e41f4b71Sopenharmony_ci### 2. A non-sendable class can inherit only from a non-sendable class.
233e41f4b71Sopenharmony_ci
234e41f4b71Sopenharmony_ci**Positive example:**
235e41f4b71Sopenharmony_ci```ts
236e41f4b71Sopenharmony_ciclass A {
237e41f4b71Sopenharmony_ci  constructor() {
238e41f4b71Sopenharmony_ci  }
239e41f4b71Sopenharmony_ci}
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ciclass B extends A {
242e41f4b71Sopenharmony_ci  constructor() {
243e41f4b71Sopenharmony_ci    super()
244e41f4b71Sopenharmony_ci  }
245e41f4b71Sopenharmony_ci}
246e41f4b71Sopenharmony_ci```
247e41f4b71Sopenharmony_ci
248e41f4b71Sopenharmony_ci**Negative example:**
249e41f4b71Sopenharmony_ci```ts
250e41f4b71Sopenharmony_ci@Sendable
251e41f4b71Sopenharmony_ciclass A {
252e41f4b71Sopenharmony_ci  constructor() {
253e41f4b71Sopenharmony_ci  }
254e41f4b71Sopenharmony_ci}
255e41f4b71Sopenharmony_ci
256e41f4b71Sopenharmony_ciclass B extends A {
257e41f4b71Sopenharmony_ci  constructor() {
258e41f4b71Sopenharmony_ci    super()
259e41f4b71Sopenharmony_ci  }
260e41f4b71Sopenharmony_ci}
261e41f4b71Sopenharmony_ci```
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci### 3. A non-sendable class can implement only a non-sendable interface.
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci**Positive example:**
266e41f4b71Sopenharmony_ci```ts
267e41f4b71Sopenharmony_ciinterface I {};
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ciclass B implements I {};
270e41f4b71Sopenharmony_ci```
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci**Negative example:**
273e41f4b71Sopenharmony_ci```ts
274e41f4b71Sopenharmony_ciimport { lang } from '@kit.ArkTS';
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_citype ISendable = lang.ISendable;
277e41f4b71Sopenharmony_ci
278e41f4b71Sopenharmony_ciinterface I extends ISendable {};
279e41f4b71Sopenharmony_ci
280e41f4b71Sopenharmony_ciclass B implements I {};
281e41f4b71Sopenharmony_ci```
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ci### 4. The member variables of a sendable class or interface must be of a sendable data type.
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci**Positive example:**
286e41f4b71Sopenharmony_ci```ts
287e41f4b71Sopenharmony_ci@Sendable
288e41f4b71Sopenharmony_ciclass A {
289e41f4b71Sopenharmony_ci  constructor() {
290e41f4b71Sopenharmony_ci  }
291e41f4b71Sopenharmony_ci  a: number = 0;
292e41f4b71Sopenharmony_ci}
293e41f4b71Sopenharmony_ci```
294e41f4b71Sopenharmony_ci
295e41f4b71Sopenharmony_ci**Negative example:**
296e41f4b71Sopenharmony_ci```ts
297e41f4b71Sopenharmony_ci@Sendable
298e41f4b71Sopenharmony_ciclass A {
299e41f4b71Sopenharmony_ci  constructor() {
300e41f4b71Sopenharmony_ci  }
301e41f4b71Sopenharmony_ci  b: Array<number> = [1, 2, 3] // collections.Array must be used.
302e41f4b71Sopenharmony_ci}
303e41f4b71Sopenharmony_ci```
304e41f4b71Sopenharmony_ci
305e41f4b71Sopenharmony_ci### 5. The member variables of a sendable class or interface cannot use the exclamation mark (!) for assertion.
306e41f4b71Sopenharmony_ci
307e41f4b71Sopenharmony_ci**Positive example:**
308e41f4b71Sopenharmony_ci```ts
309e41f4b71Sopenharmony_ci@Sendable
310e41f4b71Sopenharmony_ciclass A {
311e41f4b71Sopenharmony_ci  constructor() {
312e41f4b71Sopenharmony_ci  }
313e41f4b71Sopenharmony_ci  a: number = 0;
314e41f4b71Sopenharmony_ci}
315e41f4b71Sopenharmony_ci```
316e41f4b71Sopenharmony_ci
317e41f4b71Sopenharmony_ci**Negative example:**
318e41f4b71Sopenharmony_ci```ts
319e41f4b71Sopenharmony_ci@Sendable
320e41f4b71Sopenharmony_ciclass A {
321e41f4b71Sopenharmony_ci  constructor() {
322e41f4b71Sopenharmony_ci  }
323e41f4b71Sopenharmony_ci  a!: number;
324e41f4b71Sopenharmony_ci}
325e41f4b71Sopenharmony_ci```
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ci### 6. The member variables of a sendable class or interface do not support computed property names.
328e41f4b71Sopenharmony_ci
329e41f4b71Sopenharmony_ci**Positive example:**
330e41f4b71Sopenharmony_ci```ts
331e41f4b71Sopenharmony_ci@Sendable
332e41f4b71Sopenharmony_ciclass A {
333e41f4b71Sopenharmony_ci    num1: number = 1;
334e41f4b71Sopenharmony_ci    num2: number = 2;
335e41f4b71Sopenharmony_ci    add(): number {
336e41f4b71Sopenharmony_ci      return this.num1 + this.num2;
337e41f4b71Sopenharmony_ci    }
338e41f4b71Sopenharmony_ci}
339e41f4b71Sopenharmony_ci```
340e41f4b71Sopenharmony_ci
341e41f4b71Sopenharmony_ci**Negative example:**
342e41f4b71Sopenharmony_ci```ts
343e41f4b71Sopenharmony_cienum B {
344e41f4b71Sopenharmony_ci    b1 = "bbb"
345e41f4b71Sopenharmony_ci}
346e41f4b71Sopenharmony_ci@Sendable
347e41f4b71Sopenharmony_ciclass A {
348e41f4b71Sopenharmony_ci    ["aaa"]: number = 1; // ["aaa"] is allowed in other classes in ets files
349e41f4b71Sopenharmony_ci    [B.b1]: number = 2; // [B.b1] is allowed in other classes in ets files
350e41f4b71Sopenharmony_ci}
351e41f4b71Sopenharmony_ci```
352e41f4b71Sopenharmony_ci
353e41f4b71Sopenharmony_ci### 7. The template type of a sendable class, collections.Array, collections.Map, and collections.Set in the generic class must be Sendable.
354e41f4b71Sopenharmony_ci
355e41f4b71Sopenharmony_ci**Positive example:**
356e41f4b71Sopenharmony_ci```ts
357e41f4b71Sopenharmony_ciimport { collections } from '@kit.ArkTS';
358e41f4b71Sopenharmony_ci
359e41f4b71Sopenharmony_citry {
360e41f4b71Sopenharmony_ci  let arr1: collections.Array<number> = new collections.Array<number>();
361e41f4b71Sopenharmony_ci  let num: number = 1;
362e41f4b71Sopenharmony_ci  arr1.push(num)
363e41f4b71Sopenharmony_ci} catch (e) {
364e41f4b71Sopenharmony_ci  console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);
365e41f4b71Sopenharmony_ci}
366e41f4b71Sopenharmony_ci```
367e41f4b71Sopenharmony_ci
368e41f4b71Sopenharmony_ci**Negative example:**
369e41f4b71Sopenharmony_ci```ts
370e41f4b71Sopenharmony_ciimport { collections } from '@kit.ArkTS';
371e41f4b71Sopenharmony_ci
372e41f4b71Sopenharmony_citry {
373e41f4b71Sopenharmony_ci  let arr1: collections.Array<Array<number>> = new collections.Array<Array<number>>();
374e41f4b71Sopenharmony_ci  let arr2: Array<number> = new Array<number>()
375e41f4b71Sopenharmony_ci  arr2.push(1)
376e41f4b71Sopenharmony_ci  arr1.push(arr2)
377e41f4b71Sopenharmony_ci} catch (e) {
378e41f4b71Sopenharmony_ci  console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);
379e41f4b71Sopenharmony_ci}
380e41f4b71Sopenharmony_ci```
381e41f4b71Sopenharmony_ci
382e41f4b71Sopenharmony_ci### 8. Variables defined in the context of the current module cannot be used in a sendable class.
383e41f4b71Sopenharmony_ci
384e41f4b71Sopenharmony_ciBecause the context of a sendable object varies among concurrent instances, direct access may cause unexpected behavior. A sendable object cannot use the variables defined in the context of the current module. Otherwise, a compile-time error is reported.
385e41f4b71Sopenharmony_ci
386e41f4b71Sopenharmony_ci> **NOTE**
387e41f4b71Sopenharmony_ci>
388e41f4b71Sopenharmony_ci> Since API version 12, a sendable class object of the top level can be used internally by the sendable class itself.
389e41f4b71Sopenharmony_ci
390e41f4b71Sopenharmony_ci**Positive example:**
391e41f4b71Sopenharmony_ci```ts
392e41f4b71Sopenharmony_ciimport { lang } from '@kit.ArkTS';
393e41f4b71Sopenharmony_ci
394e41f4b71Sopenharmony_citype ISendable = lang.ISendable;
395e41f4b71Sopenharmony_ci
396e41f4b71Sopenharmony_ciinterface I extends ISendable {}
397e41f4b71Sopenharmony_ci
398e41f4b71Sopenharmony_ci@Sendable
399e41f4b71Sopenharmony_ciclass B implements I {
400e41f4b71Sopenharmony_ci  static o: number = 1;
401e41f4b71Sopenharmony_ci  static bar(): B {
402e41f4b71Sopenharmony_ci    return new B();
403e41f4b71Sopenharmony_ci  }
404e41f4b71Sopenharmony_ci}
405e41f4b71Sopenharmony_ci
406e41f4b71Sopenharmony_ci@Sendable
407e41f4b71Sopenharmony_ciclass C {
408e41f4b71Sopenharmony_ci  v: I = new B();
409e41f4b71Sopenharmony_ci  u: number = B.o;
410e41f4b71Sopenharmony_ci
411e41f4b71Sopenharmony_ci  foo() {
412e41f4b71Sopenharmony_ci    return B.bar();
413e41f4b71Sopenharmony_ci  }
414e41f4b71Sopenharmony_ci}
415e41f4b71Sopenharmony_ci```
416e41f4b71Sopenharmony_ci
417e41f4b71Sopenharmony_ci**Negative example:**
418e41f4b71Sopenharmony_ci```ts
419e41f4b71Sopenharmony_ciimport { lang } from '@kit.ArkTS';
420e41f4b71Sopenharmony_ci
421e41f4b71Sopenharmony_citype ISendable = lang.ISendable;
422e41f4b71Sopenharmony_ci
423e41f4b71Sopenharmony_ciinterface I extends ISendable {}
424e41f4b71Sopenharmony_ci
425e41f4b71Sopenharmony_ci@Sendable
426e41f4b71Sopenharmony_ciclass B implements I {}
427e41f4b71Sopenharmony_ci
428e41f4b71Sopenharmony_cifunction bar(): B {
429e41f4b71Sopenharmony_ci  return new B();
430e41f4b71Sopenharmony_ci}
431e41f4b71Sopenharmony_ci
432e41f4b71Sopenharmony_cilet b = new B();
433e41f4b71Sopenharmony_ci
434e41f4b71Sopenharmony_ci{
435e41f4b71Sopenharmony_ci  @Sendable
436e41f4b71Sopenharmony_ci  class A implements I {}
437e41f4b71Sopenharmony_ci
438e41f4b71Sopenharmony_ci  @Sendable
439e41f4b71Sopenharmony_ci  class C {
440e41f4b71Sopenharmony_ci    u: I = bar(); // bar is not a sendable class object. A compile-time error is reported.
441e41f4b71Sopenharmony_ci    v: I = new A(); // A is not defined in the top level. A compile-time error is reported.
442e41f4b71Sopenharmony_ci
443e41f4b71Sopenharmony_ci    foo() {
444e41f4b71Sopenharmony_ci      return b; // b is not a sendable class object but an instance of the sendable class. A compile-time error is reported.
445e41f4b71Sopenharmony_ci    }
446e41f4b71Sopenharmony_ci  }
447e41f4b71Sopenharmony_ci}
448e41f4b71Sopenharmony_ci
449e41f4b71Sopenharmony_ci```
450e41f4b71Sopenharmony_ci
451e41f4b71Sopenharmony_ci### 9. A sendable class and sendable function can only use the @Sendable decorator.
452e41f4b71Sopenharmony_ci
453e41f4b71Sopenharmony_ciIf the class decorator is defined in a .ts file, any modification to the class layout causes a runtime error.
454e41f4b71Sopenharmony_ci
455e41f4b71Sopenharmony_ci**Positive example:**
456e41f4b71Sopenharmony_ci```ts
457e41f4b71Sopenharmony_ci@Sendable
458e41f4b71Sopenharmony_ciclass A {
459e41f4b71Sopenharmony_ci  num: number = 1;
460e41f4b71Sopenharmony_ci}
461e41f4b71Sopenharmony_ci```
462e41f4b71Sopenharmony_ci
463e41f4b71Sopenharmony_ci**Negative example:**
464e41f4b71Sopenharmony_ci```ts
465e41f4b71Sopenharmony_ci@Sendable
466e41f4b71Sopenharmony_ci@Observed
467e41f4b71Sopenharmony_ciclass C {
468e41f4b71Sopenharmony_ci  num: number = 1;
469e41f4b71Sopenharmony_ci}
470e41f4b71Sopenharmony_ci```
471e41f4b71Sopenharmony_ci
472e41f4b71Sopenharmony_ci### 10. The Sendable type cannot be initialized using an object literal or array literal.
473e41f4b71Sopenharmony_ci
474e41f4b71Sopenharmony_ciA sendable data type can be created only by using the **new** expression of the Sendable type.
475e41f4b71Sopenharmony_ci
476e41f4b71Sopenharmony_ci**Positive example:**
477e41f4b71Sopenharmony_ci```ts
478e41f4b71Sopenharmony_ciimport { collections } from '@kit.ArkTS';
479e41f4b71Sopenharmony_ci
480e41f4b71Sopenharmony_cilet arr1: collections.Array<number> = new collections.Array<number>(1, 2, 3); // The type is Sendable.
481e41f4b71Sopenharmony_ci```
482e41f4b71Sopenharmony_ci
483e41f4b71Sopenharmony_ci**Negative example:**
484e41f4b71Sopenharmony_ci```ts
485e41f4b71Sopenharmony_ciimport { collections } from '@kit.ArkTS';
486e41f4b71Sopenharmony_ci
487e41f4b71Sopenharmony_cilet arr2: collections.Array<number> = [1, 2, 3]; // The type is not Sendable. A compile-time error is reported.
488e41f4b71Sopenharmony_cilet arr3: number[] = [1, 2, 3]; // The type is not Sendable. No error is reported.
489e41f4b71Sopenharmony_cilet arr4: number[] = new collections.Array<number>(1, 2, 3); // A compile-time error is reported.
490e41f4b71Sopenharmony_ci```
491e41f4b71Sopenharmony_ci
492e41f4b71Sopenharmony_ci### 11. A non-sendable type cannot be converted to a sendable type using **as**.
493e41f4b71Sopenharmony_ci
494e41f4b71Sopenharmony_ci> **NOTE**
495e41f4b71Sopenharmony_ci>
496e41f4b71Sopenharmony_ci> A sendable type must be compatible with a non-sendable type without violating the sendable usage rules. Therefore, a sendable type can be converted to a non-sendable type using **as**.
497e41f4b71Sopenharmony_ci
498e41f4b71Sopenharmony_ci**Positive example:**
499e41f4b71Sopenharmony_ci```ts
500e41f4b71Sopenharmony_ciclass A {
501e41f4b71Sopenharmony_ci  state: number = 0;
502e41f4b71Sopenharmony_ci}
503e41f4b71Sopenharmony_ci
504e41f4b71Sopenharmony_ci@Sendable
505e41f4b71Sopenharmony_ciclass SendableA {
506e41f4b71Sopenharmony_ci  state: number = 0;
507e41f4b71Sopenharmony_ci}
508e41f4b71Sopenharmony_ci
509e41f4b71Sopenharmony_cilet a1: A = new SendableA() as A;
510e41f4b71Sopenharmony_ci```
511e41f4b71Sopenharmony_ci
512e41f4b71Sopenharmony_ci**Negative example:**
513e41f4b71Sopenharmony_ci```ts
514e41f4b71Sopenharmony_ciclass A {
515e41f4b71Sopenharmony_ci  state: number = 0;
516e41f4b71Sopenharmony_ci}
517e41f4b71Sopenharmony_ci
518e41f4b71Sopenharmony_ci@Sendable
519e41f4b71Sopenharmony_ciclass SendableA {
520e41f4b71Sopenharmony_ci  state: number = 0;
521e41f4b71Sopenharmony_ci}
522e41f4b71Sopenharmony_ci
523e41f4b71Sopenharmony_cilet a2: SendableA = new A() as SendableA;
524e41f4b71Sopenharmony_ci```
525e41f4b71Sopenharmony_ci
526e41f4b71Sopenharmony_ci### 12. An arrow function is not sendable.
527e41f4b71Sopenharmony_ciAn arrow function cannot be decorated by @Sendable.
528e41f4b71Sopenharmony_ci
529e41f4b71Sopenharmony_ci**Positive example:**
530e41f4b71Sopenharmony_ci```ts
531e41f4b71Sopenharmony_ci@Sendable
532e41f4b71Sopenharmony_citype SendableFuncType = () => void;
533e41f4b71Sopenharmony_ci
534e41f4b71Sopenharmony_ci@Sendable
535e41f4b71Sopenharmony_cifunction SendableFunc() {
536e41f4b71Sopenharmony_ci  console.info("Sendable func");
537e41f4b71Sopenharmony_ci}
538e41f4b71Sopenharmony_ci
539e41f4b71Sopenharmony_ci@Sendable
540e41f4b71Sopenharmony_ciclass SendableClass {
541e41f4b71Sopenharmony_ci  constructor(f: SendableFuncType) {
542e41f4b71Sopenharmony_ci    this.func = f;
543e41f4b71Sopenharmony_ci  }
544e41f4b71Sopenharmony_ci  func: SendableFuncType;
545e41f4b71Sopenharmony_ci}
546e41f4b71Sopenharmony_ci
547e41f4b71Sopenharmony_cilet sendableClass = new SendableClass(SendableFunc)
548e41f4b71Sopenharmony_ci```
549e41f4b71Sopenharmony_ci
550e41f4b71Sopenharmony_ci**Negative example:**
551e41f4b71Sopenharmony_ci```ts
552e41f4b71Sopenharmony_ci@Sendable
553e41f4b71Sopenharmony_citype SendableFuncType = () => void;
554e41f4b71Sopenharmony_cilet func: SendableFuncType = () => {}; // A compile-time error is reported.
555e41f4b71Sopenharmony_ci
556e41f4b71Sopenharmony_ci@Sendable
557e41f4b71Sopenharmony_ciclass SendableClass {
558e41f4b71Sopenharmony_ci  func: SendableFuncType = () => {}; // A compile-time error is reported.
559e41f4b71Sopenharmony_ci}
560e41f4b71Sopenharmony_ci```
561e41f4b71Sopenharmony_ci
562e41f4b71Sopenharmony_ci### 13. \@Sendable supports type decoration for functions only.
563e41f4b71Sopenharmony_ciThe @Sendable decorator supports type decoration for functions only.
564e41f4b71Sopenharmony_ci
565e41f4b71Sopenharmony_ci**Positive example:**
566e41f4b71Sopenharmony_ci```ts
567e41f4b71Sopenharmony_ci@Sendable
568e41f4b71Sopenharmony_citype SendableFuncType = () => void;
569e41f4b71Sopenharmony_ci```
570e41f4b71Sopenharmony_ci
571e41f4b71Sopenharmony_ci**Negative example:**
572e41f4b71Sopenharmony_ci```ts
573e41f4b71Sopenharmony_ci@Sendable
574e41f4b71Sopenharmony_citype A = number; // A compile-time error is reported.
575e41f4b71Sopenharmony_ci
576e41f4b71Sopenharmony_ci@Sendable
577e41f4b71Sopenharmony_ciclass C {}
578e41f4b71Sopenharmony_ci
579e41f4b71Sopenharmony_ci@Sendable
580e41f4b71Sopenharmony_citype D = C; // A compile-time error is reported.
581e41f4b71Sopenharmony_ci```
582e41f4b71Sopenharmony_ci
583e41f4b71Sopenharmony_ci## Precautions
584e41f4b71Sopenharmony_ci
585e41f4b71Sopenharmony_ciWhen using **Sendable** in HAR, enable the configuration of generating TS files. For details, see [Building TS Files](../quick-start/har-package.md#building-ts-files).
586e41f4b71Sopenharmony_ci
587e41f4b71Sopenharmony_ci## Rules for Interaction with TS/JS
588e41f4b71Sopenharmony_ci
589e41f4b71Sopenharmony_ci### ArkTS General Rules (Only for Sendable Objects Currently)
590e41f4b71Sopenharmony_ci
591e41f4b71Sopenharmony_ci| Rule Description       |
592e41f4b71Sopenharmony_ci| ----------- |
593e41f4b71Sopenharmony_ci| When a sendable object is passed to a TS/JS interface, the object layout cannot be operated (adding or deleting properties, or changing property types).|
594e41f4b71Sopenharmony_ci| When a sendable object is set to a TS/JS object, the object layout cannot be operated (adding or deleting properties, or changing property types) after the TS/JS object obtains the sendable object.|
595e41f4b71Sopenharmony_ci| When a sendable object is placed in a TS/JS container, the object layout cannot be operated (adding or deleting properties, or changing property types) after the TS/JS object obtains the sendable object.|
596e41f4b71Sopenharmony_ci
597e41f4b71Sopenharmony_ci> **NOTE**
598e41f4b71Sopenharmony_ci>
599e41f4b71Sopenharmony_ci> Changes of the property types do not include changes of the sendable object types, for example, from Sendable class A to Sendable class B.
600e41f4b71Sopenharmony_ci
601e41f4b71Sopenharmony_ci
602e41f4b71Sopenharmony_ci### Native API Rules (Only for Sendable Objects Currently)
603e41f4b71Sopenharmony_ci
604e41f4b71Sopenharmony_ci| Rule Description       |
605e41f4b71Sopenharmony_ci| ----------- |
606e41f4b71Sopenharmony_ci| Do not delete properties. The **napi_delete_property** interface cannot be used.|
607e41f4b71Sopenharmony_ci| Do not add properties. The following interfaces cannot be used: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.	|
608e41f4b71Sopenharmony_ci| Do not modify property types. The following interfaces cannot be used: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.|
609e41f4b71Sopenharmony_ci| Symbol-related interfaces and types are not supported. The following interfaces cannot be used: **napi_create_symbol**, **napi_is_symbol_object**, and **napi_symbol**.|
610e41f4b71Sopenharmony_ci
611e41f4b71Sopenharmony_ci
612e41f4b71Sopenharmony_ci## When to Use
613e41f4b71Sopenharmony_ci
614e41f4b71Sopenharmony_ciSendable objects can be passed by reference between concurrent instances. Compared with serialization, pass-by-reference is more efficient and does not cause the loss of member methods carried in the class. The sendable mode is used in the following scenarios:
615e41f4b71Sopenharmony_ci1. Transferring a large amount of data (for example, more than 100 KB) across concurrent instances
616e41f4b71Sopenharmony_ci2. Passing a class instance object carrying methods across concurrent instances
617e41f4b71Sopenharmony_ci
618e41f4b71Sopenharmony_ci### Transferring a Large Amount of Data Across Concurrent Instances
619e41f4b71Sopenharmony_ci
620e41f4b71Sopenharmony_ciThe 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.
621e41f4b71Sopenharmony_ci
622e41f4b71Sopenharmony_ci**Example**
623e41f4b71Sopenharmony_ci```ts
624e41f4b71Sopenharmony_ci// index.ets
625e41f4b71Sopenharmony_ciimport { taskpool } from '@kit.ArkTS';
626e41f4b71Sopenharmony_ciimport { testTypeA, testTypeB, Test } from './sendable'
627e41f4b71Sopenharmony_ci
628e41f4b71Sopenharmony_ci// Simulate data processing in a concurrent function.
629e41f4b71Sopenharmony_ci@Concurrent
630e41f4b71Sopenharmony_ciasync function taskFunc(obj: Test) {
631e41f4b71Sopenharmony_ci  console.info("test task res1 is: " + obj.data1.name + " res2 is: " + obj.data2.name);
632e41f4b71Sopenharmony_ci}
633e41f4b71Sopenharmony_ci
634e41f4b71Sopenharmony_ciasync function test() {
635e41f4b71Sopenharmony_ci  // Use TaskPool for data transfer.
636e41f4b71Sopenharmony_ci  let a: testTypeA = new testTypeA("testTypeA");
637e41f4b71Sopenharmony_ci  let b: testTypeB = new testTypeB("testTypeB");
638e41f4b71Sopenharmony_ci  let obj: Test = new Test(a, b);
639e41f4b71Sopenharmony_ci  let task: taskpool.Task = new taskpool.Task(taskFunc, obj);
640e41f4b71Sopenharmony_ci  await taskpool.execute(task);
641e41f4b71Sopenharmony_ci}
642e41f4b71Sopenharmony_ci
643e41f4b71Sopenharmony_citest();
644e41f4b71Sopenharmony_ci```
645e41f4b71Sopenharmony_ci
646e41f4b71Sopenharmony_ci```ts
647e41f4b71Sopenharmony_ci// sendable.ets
648e41f4b71Sopenharmony_ci// Assemble the data of a large size in a sendable class.
649e41f4b71Sopenharmony_ci@Sendable
650e41f4b71Sopenharmony_ciexport class testTypeA {
651e41f4b71Sopenharmony_ci  name: string = "A";
652e41f4b71Sopenharmony_ci  constructor(name: string) {
653e41f4b71Sopenharmony_ci    this.name = name;
654e41f4b71Sopenharmony_ci  }
655e41f4b71Sopenharmony_ci}
656e41f4b71Sopenharmony_ci
657e41f4b71Sopenharmony_ci@Sendable
658e41f4b71Sopenharmony_ciexport class testTypeB {
659e41f4b71Sopenharmony_ci  name: string = "B";
660e41f4b71Sopenharmony_ci  constructor(name: string) {
661e41f4b71Sopenharmony_ci    this.name = name;
662e41f4b71Sopenharmony_ci  }
663e41f4b71Sopenharmony_ci}
664e41f4b71Sopenharmony_ci
665e41f4b71Sopenharmony_ci@Sendable
666e41f4b71Sopenharmony_ciexport class Test {
667e41f4b71Sopenharmony_ci  data1: testTypeA;
668e41f4b71Sopenharmony_ci  data2: testTypeB;
669e41f4b71Sopenharmony_ci  constructor(arg1: testTypeA, arg2: testTypeB) {
670e41f4b71Sopenharmony_ci    this.data1 = arg1;
671e41f4b71Sopenharmony_ci    this.data2 = arg2;
672e41f4b71Sopenharmony_ci  }
673e41f4b71Sopenharmony_ci}
674e41f4b71Sopenharmony_ci```
675e41f4b71Sopenharmony_ci
676e41f4b71Sopenharmony_ci
677e41f4b71Sopenharmony_ci### Passing a Class Instance Object Carrying Methods Across Concurrent Instances
678e41f4b71Sopenharmony_ci
679e41f4b71Sopenharmony_ciMethods 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, use the [ASON tool](../reference/apis-arkts/js-apis-arkts-utils.md#arktsutilsason).
680e41f4b71Sopenharmony_ci
681e41f4b71Sopenharmony_ci**Example**
682e41f4b71Sopenharmony_ci```ts
683e41f4b71Sopenharmony_ci// Index.ets
684e41f4b71Sopenharmony_ciimport { taskpool, ArkTSUtils } from '@kit.ArkTS'
685e41f4b71Sopenharmony_ciimport { SendableTestClass, ISendable } from './sendable'
686e41f4b71Sopenharmony_ci
687e41f4b71Sopenharmony_ci// Simulate data processing in a concurrent function.
688e41f4b71Sopenharmony_ci@Concurrent
689e41f4b71Sopenharmony_ciasync function taskFunc(sendableObj: SendableTestClass) {
690e41f4b71Sopenharmony_ci  console.info("SendableTestClass: name is: " + sendableObj.printName() + ", age is: " + sendableObj.printAge() + ", sex is: " + sendableObj.printSex());
691e41f4b71Sopenharmony_ci  sendableObj.setAge(28);
692e41f4b71Sopenharmony_ci  console.info("SendableTestClass: age is: " + sendableObj.printAge());
693e41f4b71Sopenharmony_ci
694e41f4b71Sopenharmony_ci  // Parse the sendableObj.arr data to generate a JSON string.
695e41f4b71Sopenharmony_ci  let str = ArkTSUtils.ASON.stringify(sendableObj.arr);
696e41f4b71Sopenharmony_ci  console.info("SendableTestClass: str is: " + str);
697e41f4b71Sopenharmony_ci
698e41f4b71Sopenharmony_ci  // Parse the data and generate ISendable data.
699e41f4b71Sopenharmony_ci  let jsonStr = '{"name": "Alexa", "age": 23, "sex": "female"}';
700e41f4b71Sopenharmony_ci  let obj = ArkTSUtils.ASON.parse(jsonStr) as ISendable;
701e41f4b71Sopenharmony_ci  console.info("SendableTestClass: type is: " + typeof obj);
702e41f4b71Sopenharmony_ci  console.info("SendableTestClass: name is: " + (obj as object)?.["name"]); // output: 'Alexa'
703e41f4b71Sopenharmony_ci  console.info("SendableTestClass: age is: " + (obj as object)?.["age"]); // output: 23
704e41f4b71Sopenharmony_ci  console.info("SendableTestClass: sex is: " + (obj as object)?.["sex"]); // output: 'female'
705e41f4b71Sopenharmony_ci}
706e41f4b71Sopenharmony_ciasync function test() {
707e41f4b71Sopenharmony_ci  // Use TaskPool for data transfer.
708e41f4b71Sopenharmony_ci  let obj: SendableTestClass = new SendableTestClass();
709e41f4b71Sopenharmony_ci  let task: taskpool.Task = new taskpool.Task(taskFunc, obj);
710e41f4b71Sopenharmony_ci  await taskpool.execute(task);
711e41f4b71Sopenharmony_ci}
712e41f4b71Sopenharmony_ci
713e41f4b71Sopenharmony_citest();
714e41f4b71Sopenharmony_ci```
715e41f4b71Sopenharmony_ci
716e41f4b71Sopenharmony_ci```ts
717e41f4b71Sopenharmony_ci// sendable.ets
718e41f4b71Sopenharmony_ci// Define a Test class to simulate the transfer of a class carrying methods.
719e41f4b71Sopenharmony_ciimport { lang, collections  } from '@kit.ArkTS'
720e41f4b71Sopenharmony_ci
721e41f4b71Sopenharmony_ciexport type ISendable = lang.ISendable;
722e41f4b71Sopenharmony_ci
723e41f4b71Sopenharmony_ci@Sendable
724e41f4b71Sopenharmony_ciexport class SendableTestClass {
725e41f4b71Sopenharmony_ci  name: string = 'John';
726e41f4b71Sopenharmony_ci  age: number = 20;
727e41f4b71Sopenharmony_ci  sex: string = "man";
728e41f4b71Sopenharmony_ci  arr: collections.Array<number> = new collections.Array<number>(1, 2, 3);
729e41f4b71Sopenharmony_ci  constructor() {
730e41f4b71Sopenharmony_ci  }
731e41f4b71Sopenharmony_ci  setAge(age: number) : void {
732e41f4b71Sopenharmony_ci    this.age = age;
733e41f4b71Sopenharmony_ci  }
734e41f4b71Sopenharmony_ci
735e41f4b71Sopenharmony_ci  printName(): string {
736e41f4b71Sopenharmony_ci    return this.name;
737e41f4b71Sopenharmony_ci  }
738e41f4b71Sopenharmony_ci
739e41f4b71Sopenharmony_ci  printAge(): number {
740e41f4b71Sopenharmony_ci    return this.age;
741e41f4b71Sopenharmony_ci  }
742e41f4b71Sopenharmony_ci
743e41f4b71Sopenharmony_ci  printSex(): string {
744e41f4b71Sopenharmony_ci    return this.sex;
745e41f4b71Sopenharmony_ci  }
746e41f4b71Sopenharmony_ci}
747e41f4b71Sopenharmony_ci```
748