• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Worker
2
3Worker primarily provides a multithreaded runtime environment for applications, allowing them to separate from the host thread during execution. This enables scripts to run in background threads for time-consuming operations, avoiding blocking the host thread during compute-intensive or high-latency tasks. For details about the APIs and their usage, see [Worker](../reference/apis-arkts/js-apis-worker.md).
4
5
6## Worker Operating Mechanism
7
8**Figure 1** Worker operating mechanism
9
10![worker](figures/worker.png)
11
12The thread that creates a Worker is referred to as the host thread (not limited to the main thread; Worker threads can also create its child Workers). The Worker thread (also called actor thread) is the thread on which the Worker itself runs. Each Worker thread and the host thread have independent instances, including separate execution environments, objects, and code segments. Therefore, there is a certain memory overhead associated with starting each Worker, and the number of Worker threads should be limited. Worker threads and the host thread communicate through a message-passing mechanism, using serialization to complete the exchange of commands and data.
13
14
15## Precautions for Worker
16
17- A Worker can be created manually or automatically. The automatic mode is recommended. In manual mode, you must also synchronize the related configuration. For details, see [Precautions for Creating a Worker](#precautions-for-creating-a-worker).
18- When using Worker capabilities, the URL of the Worker thread file passed in the constructor varies by API version. For specifics, see [Precautions for File URLs](#precautions-for-file-urls).
19- After a Worker is created, its lifecycle must be managed manually. A maximum of 64 Worker threads can run simultaneously, and the total number cannot exceed 80, including those created with [napi_create_ark_runtime](../reference/native-lib/napi.md#napi_create_ark_runtime). For details, see [Precautions for Lifecycle Management](#precautions-for-lifecycle-management).
20- The context objects in different threads are different. Therefore, Worker threads can use only thread-safe libraries. For example, non-thread-safe UI-related libraries cannot be used in Worker threads.
21- A maximum of 16 MB data can be serialized at a time.
22- When using the Worker module, you are advised to register the **onAllErrors** callback in the host thread in API version 18 or later to capture various exceptions that may occur during the lifecycle of the Worker thread. In versions earlier than API version 18, register the **onerror** callback. If neither of them is registered, JS crash occurs when the Worker thread is abnormal. Note that the **onerror** callback can only capture synchronous exceptions within the **onmessage** callback. Once an exception is captured, the Worker thread will proceed to the destruction process and cannot be used. For details, see [Behavior Differences Between onAllErrors and onerror](#behavior-differences-between-onallerrors-and-onerror).
23- Worker thread files cannot be used across HAPs.
24- Before referencing a Worker in a HAR or HSP, configure the dependency on the HAR or HSP. For details, see [Referencing a Shared Package](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-har-import).
25- [AppStorage](../ui/state-management/arkts-appstorage.md) cannot be used in Worker threads.
26- Starting from API version 18, the priority of the Worker thread can be specified in the [WorkerOptions](../reference/apis-arkts/js-apis-worker.md#workeroptions) parameter of the constructor.
27
28### Precautions for Creating a Worker
29
30The Worker thread file must be placed in the ***{moduleName}*/src/main/ets/** directory to be included in the application package. There are two ways to create Worker thread directories and files: manually and automatically.
31
32- Manual creation: Manually create the **worker.ets** file in the **workers** folder in the **ets** directory, and configure the related field in **build-profile.json5** so that the Worker thread file can be packed into the application package.
33
34  Stage model:
35
36  ```json
37  "buildOption": {
38    "sourceOption": {
39      "workers": [
40        "./src/main/ets/workers/worker.ets"
41      ]
42    }
43  }
44  ```
45  <!-- @[manual_create_worker](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/build-profile.json5) -->
46
47  FA model:
48
49  ```json
50  "buildOption": {
51    "sourceOption": {
52      "workers": [
53        "./src/main/ets/MainAbility/workers/worker.ets"
54      ]
55    }
56  }
57  ```
58
59- Automatic mode: DevEco Studio supports one-click generation of Workers. Right-click any position in the {moduleName} directory and choose **New > Worker** to generate the Worker template file and configuration information. There is no need to configure the fields in **build-profile.json5**.
60
61
62### Precautions for File URLs
63
64Before calling an API of the Worker module, you must create a Worker object. The constructor is related to the API version and requires the URL to the Worker thread file to be passed in **scriptURL**.
65
66```ts
67// Import the module.
68import { worker } from '@kit.ArkTS';
69
70// Use the following function in API version 9 and later versions:
71const worker1: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/worker.ets');
72// Use the following function in API version 8 and earlier versions:
73const worker2: worker.Worker = new worker.Worker('entry/ets/workers/worker.ets');
74```
75
76
77#### File URL Rules in Stage Model
78
79The requirements for **scriptURL** in the constructor are as follows:
80
81- **scriptURL** consists of {moduleName}/ets and {relativePath}.
82- {relativePath} is the relative path of the Worker thread file to the ***{moduleName}*/src/main/ets/** directory.
83
84(1) Loading a Worker thread file of an ability
85
86To load the Worker thread file of an ability, use the URL {moduleName}/ets/{relativePath}.
87
88```ts
89import { worker } from '@kit.ArkTS';
90
91// URL of the Worker thread file: "entry/src/main/ets/workers/worker.ets"
92const workerStage1: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/worker.ets');
93
94// URL of the Worker thread file: "testworkers/src/main/ets/ThreadFile/workers/worker.ets"
95const workerStage2: worker.ThreadWorker = new worker.ThreadWorker('testworkers/ets/ThreadFile/workers/worker.ets');
96```
97
98(2) Loading a Worker thread file from an [HSP](../quick-start/in-app-hsp.md)
99
100To load the Worker thread file from an HSP, use the URL {moduleName}/ets/{relativePath}.
101
102```ts
103import { worker } from '@kit.ArkTS';
104
105// URL of the Worker thread file: "hsp/src/main/ets/workers/worker.ets"
106const workerStage3: worker.ThreadWorker = new worker.ThreadWorker('hsp/ets/workers/worker.ets');
107```
108
109(3) Loading a Worker thread file from an [HAR](../quick-start/har-package.md)
110
111There are two scenarios for loading a Worker thread file from an HAR:
112
113- @ path loading: All types of modules load the Worker thread file from the local HAR. The URL is @{moduleName}/ets/{relativePath}.
114
115- Relative path loading: The local HAR loads the Worker thread file within the same package. The URL is the relative path of the file where the Worker object is created to the Worker thread file.
116
117>**NOTE**
118>
119>When **useNormalizedOHMUrl** is enabled (the **useNormalizedOHMUrl** field of the **strictMode** property in the application-level **build-profile.json5** file at the same level as the entry in the project directory is set to **true**) or when the HAR is used as a third-party package, the Worker thread file contained the HAR can be loaded using a relative path.
120
121```ts
122import { worker } from '@kit.ArkTS';
123
124// @ path loading:
125// URL of the Worker thread file: "har/src/main/ets/workers/worker.ets"
126const workerStage4: worker.ThreadWorker = new worker.ThreadWorker('@har/ets/workers/worker.ets');
127
128// Relative path loading:
129// URL of the Worker thread file: "har/src/main/ets/workers/worker.ets"
130// URL of the file where the Worker object is created: "har/src/main/ets/components/mainpage/MainPage.ets"
131const workerStage5: worker.ThreadWorker = new worker.ThreadWorker('../../workers/worker.ets');
132```
133
134
135#### File URL Rules in FA Model
136
137**scriptURL** in the constructor is the relative path from the Worker thread file to "{moduleName}/src/main/ets/MainAbility".
138
139```ts
140import { worker } from '@kit.ArkTS';
141
142// The following three scenarios are involved.
143
144// Scenario 1: URL of the Worker thread file: "{moduleName}/src/main/ets/MainAbility/workers/worker.ets"
145const workerFA1: worker.ThreadWorker = new worker.ThreadWorker('workers/worker.ets', {name:'first worker in FA model'});
146
147// Scenario 2: URL of the Worker thread file: "{moduleName}/src/main/ets/workers/worker.ets"
148const workerFA2: worker.ThreadWorker = new worker.ThreadWorker('../workers/worker.ets');
149
150// Scenario 3: URL of the Worker thread file: "{moduleName}/src/main/ets/MainAbility/ThreadFile/workers/worker.ets"
151const workerFA3: worker.ThreadWorker = new worker.ThreadWorker('ThreadFile/workers/worker.ets');
152```
153
154
155### Precautions for Lifecycle Management
156
157- Creating and destroying Worker consume system resources. Therefore, you are advised to manage created Workers efficiently and reuse them when possible. Idle Workers still occupy resources. When a Worker is no longer needed, call [terminate()](../reference/apis-arkts/js-apis-worker.md#terminate9) or [close()](../reference/apis-arkts/js-apis-worker.md#close9) to destroy it actively. If a Worker is in a non-running state such as destroyed or being destroyed, calling its functional interfaces will throw corresponding errors.
158
159
160- The number of Workers is determined by the memory management policy, with a set memory threshold being the smaller of 1.5 GB and 60% of the device's physical memory. Under memory constraints, a maximum of 64 Workers can run simultaneously. If an attempt is made to create more Workers than this limit, the system displays the error message "Worker initialization failure, the number of Workers exceeds the maximum." The actual number of running Workers will be adjusted in real time based on current memory usage. When the cumulative memory usage of all Workers and the main thread exceeds the set threshold, Out of Memory (OOM) error occurs, and applications may crash.
161
162
163### Behavior Differences Between onAllErrors and onerror
164
1651. Exception Capture Range
166
167    **onAllErrors** can capture global exceptions generated during the **onmessage** callback, timer callback, and file execution of the Worker thread.
168
169    **onerror** can capture only exceptions generated by synchronous methods within the **onmessage** callback of the Worker thread. It cannot capture exceptions from multithreaded callbacks or modularization-related exceptions.
170
1712. Thread State After Exception Capture
172
173    After an exception is captured by **onAllErrors**, the Worker thread remains alive and can continue to be used. This allows you to perform additional operations after an exception is captured, without worrying about the thread being terminated.
174
175    Once an exception is captured by **onerror**, the Worker thread enters the destruction process and cannot be used. This means that after **onerror** is triggered, the Worker thread will be terminated, and subsequent operations cannot proceed.
176
1773. Applicable Scenarios
178
179    **onAllErrors** applies to scenarios where all types of exceptions in the Worker thread need to be captured, especially in complex scenarios where the Worker thread must continue running after an exception occurs.
180
181    **onerror** is appropriate for simple scenarios where only synchronous exceptions in the **onmessage** callback need to be captured. Since the thread is destroyed after an exception is captured, it is best used when the Worker thread is not needed afterward.
182
183    **onAllErrors** is recommended because it provides more comprehensive exception capture capabilities and does not lead to thread termination.
184
185
186## Basic Usage Example of Worker
187
1881. Create Worker with DevEco Studio. Specifically, in DevEco Studio, right-click anywhere in the {moduleName} directory and choose **New > Worker** to automatically generate the Worker template file and configuration information. This section uses the creation of "worker" as an example.
189
190   You can also manually create Worker thread files. For specific methods and related considerations, see [Precautions for Creating a Worker](#precautions-for-creating-a-worker).
191
1922. Import the Worker module.
193
194    ```ts
195    // Index.ets
196    import { ErrorEvent, MessageEvents, worker } from '@kit.ArkTS'
197    ```
198
1993. In the host thread, call [constructor()](../reference/apis-arkts/js-apis-worker.md#constructor9) of **ThreadWorker** to create a Worker object, and register callback functions.
200
201      ```ts
202      // Index.ets
203      @Entry
204      @Component
205      struct Index {
206        @State message: string = 'Hello World';
207
208        build() {
209          RelativeContainer() {
210            Text(this.message)
211              .id('HelloWorld')
212              .fontSize(50)
213              .fontWeight(FontWeight.Bold)
214              .alignRules({
215                center: { anchor: '__container__', align: VerticalAlign.Center },
216                middle: { anchor: '__container__', align: HorizontalAlign.Center }
217              })
218              .onClick(() => {
219                // Create a Worker object.
220                let workerInstance = new worker.ThreadWorker('entry/ets/workers/worker.ets');
221
222                // Register the onmessage callback. When the host thread receives a message from the Worker thread through the workerPort.postMessage interface, this callback is invoked and executed in the host thread.
223                workerInstance.onmessage = (e: MessageEvents) => {
224                  let data: string = e.data;
225                  console.info('workerInstance onmessage is: ', data);
226                }
227
228                // Register the onAllErrors callback to capture global exceptions generated during the onmessage callback, timer callback, and file execution of the Worker thread. This callback is executed in the host thread.
229                workerInstance.onAllErrors = (err: ErrorEvent) => {
230                  console.error('workerInstance onAllErrors message is: ' + err.message);
231                }
232
233                // Register the onmessageerror callback. When the Worker object receives a message that cannot be serialized, this callback is invoked and executed in the host thread.
234                workerInstance.onmessageerror = () => {
235                  console.error('workerInstance onmessageerror');
236                }
237
238                // Register the onexit callback. When the Worker object is destroyed, this callback is invoked and executed in the host thread.
239                workerInstance.onexit = (e: number) => {
240                  // When the Worker object exits normally, the code is 0. When the Worker object exits abnormally, the code is 1.
241                  console.info('workerInstance onexit code is: ', e);
242                }
243
244                // Send a message to the Worker thread.
245                workerInstance.postMessage('1');
246              })
247          }
248          .height('100%')
249          .width('100%')
250        }
251      }
252      ```
253      <!-- @[create_worker_object_register_callback_function](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/managers/basicusage.ets) -->
254
2554. Register the callback functions in the Worker thread file.
256
257      ```ts
258      // worker.ets
259      import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
260
261      const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
262
263      // Register the onmessage callback. When the Worker thread receives a message from the host thread through the postMessage interface, this callback is invoked and executed in the Worker thread.
264      workerPort.onmessage = (e: MessageEvents) => {
265        let data: string = e.data;
266        console.info('workerPort onmessage is: ', data);
267
268        // Send a message to the main thread.
269        workerPort.postMessage('2');
270      }
271
272      // Register the onmessageerror callback. When the Worker object receives a message that cannot be serialized, this callback is invoked and executed in the Worker thread.
273      workerPort.onmessageerror = () => {
274        console.error('workerPort onmessageerror');
275      }
276
277      // Register the onerror callback. When an exception occurs during the execution of the Worker thread, this callback is invoked and executed in the Worker thread.
278      workerPort.onerror = (err: ErrorEvent) => {
279        console.error('workerPort onerror err is: ', err.message);
280      }
281      ```
282      <!-- @[register_callback_function](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/workers/worker.ets) -->
283
284
285## Loading Worker Across HARs
286
2871. Create an HAR. For details, see [HAR](../quick-start/har-package.md).
288
2892. Create the Worker thread file in the HAR.
290
291   ```ts
292   // worker.ets
293   workerPort.onmessage = (e: MessageEvents) => {
294     console.info('worker thread receive message: ', e.data);
295     workerPort.postMessage('worker thread post message to main thread');
296   }
297   ```
298   <!-- @[create_har_worker](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/har/src/main/ets/workers/worker.ets) -->
299
3003. Configure the dependency of the HAR in the **oh-package.json5** file of the entry module.
301
302   ```ts
303   // Configure the dependency of the HAR in the entry module.
304   {
305     "name": "entry",
306     "version": "1.0.0",
307     "description": "Please describe the basic information.",
308     "main": "",
309     "author": "",
310     "license": "",
311     "dependencies": {
312       "har": "file:../har"
313     }
314   }
315   ```
316   <!-- @[config_har_dependency](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/oh-package.json5) -->
317
3184. Load the Worker thread file from the HAR in the entry module.
319
320   ```ts
321   // Index.ets
322   import { worker } from '@kit.ArkTS';
323
324   @Entry
325   @Component
326   struct Index {
327     @State message: string = 'Hello World';
328
329     build() {
330       RelativeContainer() {
331         Text(this.message)
332           .id('HelloWorld')
333           .fontSize(50)
334           .fontWeight(FontWeight.Bold)
335           .alignRules({
336             center: { anchor: '__container__', align: VerticalAlign.Center },
337             middle: { anchor: '__container__', align: HorizontalAlign.Center }
338           })
339           .onClick(() => {
340             // Use @ path loading mode and load the Worker thread file from the HAR.
341             let workerInstance = new worker.ThreadWorker('@har/ets/workers/worker.ets');
342             workerInstance.onmessage = () => {
343               console.info('main thread onmessage');
344             };
345             workerInstance.postMessage('hello world');
346           })
347       }
348       .height('100%')
349       .width('100%')
350     }
351   }
352   ```
353   <!-- @[load_har_worker](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/managers/crosshar.ets) -->
354
355
356## Multi-Level Worker Lifecycle Management
357Multi-level Workers can be created. That is, a hierarchical thread relationship is formed by the mechanism of creating child Workers through parent Workers. The lifecycle of Worker threads should be manually managed. Therefore, it is important to properly manage the lifecycle of multi-level Workers. If a parent Worker is destroyed without terminating its child Workers, unpredictable results may occur. Ensure the lifecycle of child Workers always remains within the lifecycle of the parent Worker and that all child Workers are terminated before destroying the parent Worker.
358
359
360### Recommended Usage Example
361
362```ts
363// Create a Worker thread (parent Worker) in the main thread, and create a Worker thread (child Worker) in the parent Worker.
364// main thread
365import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS';
366
367// Create a parent Worker object in the main thread.
368const parentworker = new worker.ThreadWorker('entry/ets/workers/parentworker.ets');
369
370parentworker.onmessage = (e: MessageEvents) => {
371  console.info('The main thread receives a message from the parent Worker' + e.data);
372}
373
374parentworker.onexit = () => {
375  console.info('The parent Worker exits');
376}
377
378parentworker.onAllErrors = (err: ErrorEvent) => {
379  console.error('The main thread receives an error from the parent Worker ' + err);
380}
381
382parentworker.postMessage('The main thread sends a message to the parent Worker - recommended example');
383```
384<!-- @[recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/managers/recommend.ets) -->
385
386```ts
387// parentworker.ets
388import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
389
390// Create an object in the parent Worker for communicating with the main thread.
391const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
392
393workerPort.onmessage = (e : MessageEvents) => {
394  if (e.data == 'The main thread sends a message to the parent Worker - recommended example') {
395    let childworker = new worker.ThreadWorker('entry/ets/workers/childworker.ets');
396
397    childworker.onmessage = (e: MessageEvents) => {
398      console.info('The parent Worker receives a message from the child Worker' + e.data);
399      if (e.data == 'The child Worker sends information to the parent Worker') {
400        workerPort.postMessage('The parent Worker sends a message to the main thread');
401      }
402    }
403
404    childworker.onexit = () => {
405      console.info('The child Worker exits');
406      // Destroy the parent Worker after the child Worker exits.
407      workerPort.close();
408    }
409
410    childworker.onAllErrors = (err: ErrorEvent) => {
411      console.error('An error occurred on the child Worker' + err);
412    }
413
414    childworker.postMessage('The parent Worker sends a message to the child Worker - recommended example');
415  }
416}
417```
418<!-- @[recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/recommendworkers/parentworker.ets) -->
419
420```ts
421// childworker.ets
422import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
423
424// Create an object in the child Worker for communicating with the parent Worker.
425const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
426
427workerPort.onmessage = (e: MessageEvents) => {
428  if (e.data == 'The parent Worker sends a message to the child Worker - recommended example') {
429    // Service logic of the child Worker...
430    console.info('The service execution is complete, and the child Worker is destroyed');
431    workerPort.close();
432  }
433}
434```
435<!-- @[recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/recommendworkers/childworker.ets) -->
436
437
438### Not Recommended Example
439
440It is not recommended that a child Worker send messages to the parent Worker after the parent Worker is destroyed.
441
442```ts
443// main thread
444import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS';
445
446const parentworker = new worker.ThreadWorker('entry/ets/workers/parentworker.ets');
447
448parentworker.onmessage = (e: MessageEvents) => {
449  console.info('The main thread receives a message from the parent Worker' + e.data);
450}
451
452parentworker.onexit = () => {
453  console.info('The parent Worker exits');
454}
455
456parentworker.onAllErrors = (err: ErrorEvent) => {
457  console.error('The main thread receives an error from the parent Worker ' + err);
458}
459
460parentworker.postMessage('The main thread sends a message to the parent Worker');
461```
462<!-- @[not_recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/managers/notrecommendedone.ets) -->
463
464```ts
465// parentworker.ets
466import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
467
468const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
469
470workerPort.onmessage = (e : MessageEvents) => {
471  console.info('The parent Worker receives a message from the main thread' + e.data);
472
473  let childworker = new worker.ThreadWorker('entry/ets/workers/childworker.ets')
474
475  childworker.onmessage = (e: MessageEvents) => {
476    console.info('The parent Worker receives a message from the child Worker' + e.data);
477  }
478
479  childworker.onexit = () => {
480    console.info('The child Worker exits');
481    workerPort.postMessage('The parent Worker sends a message to the main thread');
482  }
483
484  childworker.onAllErrors = (err: ErrorEvent) => {
485    console.error('An error occurred on the child Worker' + err);
486  }
487
488  childworker.postMessage('The parent Worker sends a message to the child Worker');
489
490  // Destroy the parent Worker after the child Worker is created.
491  workerPort.close();
492}
493```
494<!-- @[not_recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/notrecommendedoneworker/parentworker.ets) -->
495
496```ts
497// childworker.ets
498import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
499
500const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
501
502workerPort.onmessage = (e: MessageEvents) => {
503  console.info('The child Worker receives a message' + e.data);
504
505  // After the parent Worker is destroyed, the child Worker sends a message to the parent Worker. The behavior is unpredictable.
506  workerPort.postMessage('The child Worker sends a message to the parent Worker');
507  setTimeout(() => {
508    workerPort.postMessage('The child Worker sends a message to the parent Worker');
509  }, 1000);
510}
511```
512<!-- @[not_recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/notrecommendedoneworker/childworker.ets) -->
513
514You are not advised to create a child Worker in the parent Worker when the parent Worker is initiating the destruction operation. Furthermore, avoid creating a child Worker in the parent Worker if there is any uncertainty about whether the parent Worker is initiating the destruction operation. Ensure that the parent Worker remains active before the child Worker is successfully created.
515
516```ts
517// main thread
518import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS';
519
520const parentworker = new worker.ThreadWorker('entry/ets/workers/parentworker.ets');
521
522parentworker.onmessage = (e: MessageEvents) => {
523  console.info('The main thread receives a message from the parent Worker' + e.data);
524}
525
526parentworker.onexit = () => {
527  console.info('The parent Worker exits');
528}
529
530parentworker.onAllErrors = (err: ErrorEvent) => {
531  console.error('The main thread receives an error from the parent Worker ' + err);
532}
533
534parentworker.postMessage('The main thread sends a message to the parent Worker');
535```
536<!-- @[not_recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/managers/notrecommendedtwo.ets) -->
537
538```ts
539// parentworker.ets
540import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
541
542const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
543
544workerPort.onmessage = (e : MessageEvents) => {
545  console.info('The parent Worker receives a message from the main thread' + e.data);
546
547  // Create a child Worker after the parent Worker is destroyed. The behavior is unpredictable.
548  workerPort.close();
549  let childworker = new worker.ThreadWorker('entry/ets/workers/childworker.ets');
550
551  // Destroy the parent Worker before it is confirmed that the child Worker is successfully created. The behavior is unpredictable.
552  // let childworker = new worker.ThreadWorker('entry/ets/workers/childworker.ets');
553  // workerPort.close();
554
555  childworker.onmessage = (e: MessageEvents) => {
556    console.info('The parent Worker receives a message from the child Worker' + e.data);
557  }
558
559  childworker.onexit = () => {
560    console.info('The child Worker exits');
561    workerPort.postMessage('The parent Worker sends a message to the main thread');
562  }
563
564  childworker.onAllErrors = (err: ErrorEvent) => {
565    console.error('An error occurred on the child Worker' + err);
566  }
567
568  childworker.postMessage('The parent Worker sends a message to the child Worker');
569}
570```
571<!-- @[not_recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/notrecommendedtwoworker/parentworker.ets) -->
572
573```ts
574// childworker.ets
575import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
576
577const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
578
579workerPort.onmessage = (e: MessageEvents) => {
580  console.info('The child Worker receives a message' + e.data);
581}
582```
583<!-- @[not_recommended_example](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/MultithreadedConcurrency/WorkerIntroduction/entry/src/main/ets/notrecommendedtwoworker/childworker.ets) -->
584