1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import taskpool from '@ohos.taskpool'; 17import utils from '@arkts.utils'; 18import stack from '@ohos.util.Stack'; 19import { BusinessError } from '@ohos.base'; 20import { SendableClass, a } from './SendableTest'; 21import { TestA, TestB } from './test' 22 23@Component 24export struct TaskPoolTab { 25 @State taskPoolOutPutStr: string = ''; 26 @State taskPoolInPutStr: string = ''; 27 taskPoolInPutArr: string[] = []; 28 isTaskGroup : boolean = false; 29 gStack: stack<taskpool.Task> = new stack(); 30 taskGroup: taskpool.TaskGroup = new taskpool.TaskGroup(); 31 32 33 build() { 34 Column() { 35 Text($r('app.string.Text_desc')) 36 .width("100%") 37 .height("48vp") 38 .position({ x: "7%", y: "0" }) 39 .fontFamily("HarmonyHeiTi-Medium") 40 .fontSize("16fp") 41 .fontColor("#182431") 42 .lineHeight(22) 43 .fontWeight(500) 44 45 Button() { 46 Row() { 47 Image($r('app.media.public_add')) 48 .width(20) 49 .height(20) 50 .margin({ left: 4 }) 51 Text($r('app.string.Add_task')) 52 .width("75%") 53 .height("22") 54 .fontFamily("HarmonyHeiTi-Medium") 55 .fontSize("14fp") 56 .fontColor("#182431") 57 .textAlign(TextAlign.Center) 58 .lineHeight(22) 59 .fontWeight(500) 60 } 61 } 62 .id("addButton") 63 .height("10vp") 64 .borderRadius("10vp") 65 .backgroundColor("#00000000") 66 .position({ x: "67%", y: "1.5%" }) 67 .width(135) 68 .height(35) 69 .onClick(() => { 70 this.taskAdd(); 71 }) 72 73 Button() { 74 Row() { 75 Image($r('app.media.empties')) 76 .width(20) 77 .height(20) 78 .margin({ left: 4 }) 79 Text($r('app.string.Clear_desc')) 80 .width("35%") 81 .height("22") 82 .fontFamily("HarmonyHeiTi-Medium") 83 .fontSize("14fp") 84 .fontColor("#182431") 85 .textAlign(TextAlign.Center) 86 .lineHeight(22) 87 .fontWeight(500) 88 } 89 } 90 .id("taskPoolClearButton") 91 .height("10vp") 92 .borderRadius("10vp") 93 .backgroundColor("#00000000") 94 .position({ x: "71%", y: "31.5%" }) 95 .width(135) 96 .height(35) 97 .onClick(() => { 98 this.Clear(); 99 }) 100 101 TextArea({placeholder:$r('app.string.Default_desc'), text:this.taskPoolInPutStr}) 102 .id("taskPoolInPutTextArea") 103 .width("93.3%") 104 .height("139vp") 105 .position({ x: "3.3%", y: "48vp" }) 106 .textAlign(TextAlign.Start) 107 .borderRadius("24vp") 108 .backgroundColor("#ffffff") 109 .fontFamily("HarmonyHeiTi") 110 .fontSize("16fp") 111 .fontColor("#182431") 112 .fontWeight(400) 113 .padding({ top: "8vp" , left: "16vp", right: "16vp", bottom: "21vp" }) 114 .onChange((value: string) => { 115 this.taskPoolInPutStr = value; 116 this.taskPoolInPutArr = this.taskPoolInPutStr.trim().split(','); 117 this.taskPoolOutPutStr = ''; 118 }) 119 120 Text($r('app.string.Result_desc')) 121 .width("50%") 122 .height("48") 123 .position({ x: "7%", y: "187vp" }) 124 .fontFamily("HarmonyHeiTi-Medium") 125 .fontSize("16fp") 126 .fontColor("#182431") 127 .lineHeight(22) 128 .fontWeight(500) 129 130 Scroll() { 131 Text(this.taskPoolOutPutStr) 132 .id("taskPoolOutPutText") 133 .fontFamily("HarmonyHeiTi") 134 .fontSize("16fp") 135 .fontColor("#182431") 136 .fontWeight(400) 137 .padding({ top: "8vp" , left: "16vp", right: "16vp", bottom: "21vp" }) 138 } 139 .id("taskPoolOutPutScroll") 140 .width("93.3%") 141 .height("139vp") 142 .position({ x: "3.3%", y: "235vp" }) 143 .borderRadius("24vp") 144 .backgroundColor("#ffffff") 145 .align(Alignment.TopStart) 146 147 GridRow({columns: 4, 148 gutter: { x: 12, y: 12 }, 149 breakpoints: { value: ["360vp", "480vp"]}, 150 direction: GridRowDirection.Row}) { 151 GridCol ({ span: 2, offset: 0 }) { 152 Button() { 153 Text($r('app.string.Execute_After_3s_desc')) 154 .width("100%") 155 .height("22") 156 .fontFamily("HarmonyHeiTi-Medium") 157 .fontSize("16fp") 158 .fontColor("#007DFF") 159 .textAlign(TextAlign.Center) 160 .lineHeight(22) 161 .fontWeight(500) 162 } 163 .id("exeDelayButton") 164 .height("40vp") 165 .borderRadius("20vp") 166 .backgroundColor("rgba(24,36,49,0.05)") 167 .onClick(()=>{ 168 this.executeDelay(); 169 }) 170 } 171 172 GridCol ({ span: 2, offset: 0 }) { 173 Button() { 174 Text($r('app.string.Execute_Immediately_desc')) 175 .width("100%") 176 .height("22") 177 .fontFamily("HarmonyHeiTi-Medium") 178 .fontSize("16fp") 179 .fontColor("#FFFFFF") 180 .textAlign(TextAlign.Center) 181 .lineHeight(22) 182 .fontWeight(500) 183 } 184 .id("exeImmButton") 185 .height("40vp") 186 .borderRadius("20vp") 187 .backgroundColor("#007DFF") 188 .onClick(()=>{ 189 if(this.isTaskGroup == true) { 190 this.TaskGroupExec(); 191 } else { 192 this.executeImmediately(); 193 } 194 }) 195 } 196 197 GridCol ({ span: 2, offset: 0 }) { 198 Button() { 199 Text($r('app.string.Function_Task_desc')) 200 .width("100%") 201 .height("22") 202 .fontFamily("HarmonyHeiTi-Medium") 203 .fontSize("16fp") 204 .fontColor("#007DFF") 205 .textAlign(TextAlign.Center) 206 .lineHeight(22) 207 .fontWeight(500) 208 } 209 .id("exeFunctionButton") 210 .height("40vp") 211 .borderRadius("20vp") 212 .backgroundColor("rgba(24,36,49,0.05)") 213 .onClick(()=>{ 214 this.executeFunc(); 215 }) 216 } 217 218 GridCol ({ span: 2, offset: 0 }) { 219 Button() { 220 Text($r('app.string.Cancel_Task_desc')) 221 .width("100%") 222 .height("22") 223 .fontFamily("HarmonyHeiTi-Medium") 224 .fontSize("16fp") 225 .fontColor("#FFFFFF") 226 .textAlign(TextAlign.Center) 227 .lineHeight(22) 228 .fontWeight(500) 229 } 230 .id("exeCancelButton") 231 .height("40vp") 232 .borderRadius("20vp") 233 .backgroundColor("#007DFF") 234 .onClick(()=>{ 235 this.cancelTask(); 236 }) 237 } 238 239 GridCol ({ span: 4, offset: 0 }) { 240 Button() { 241 Text($r('app.string.transferSendableClass')) 242 .width("100%") 243 .height("22") 244 .fontFamily("HarmonyHeiTi-Medium") 245 .fontSize("16fp") 246 .fontColor("#007DFF") 247 .textAlign(TextAlign.Center) 248 .lineHeight(22) 249 .fontWeight(500) 250 } 251 .id("sendableButton") 252 .height("40vp") 253 .borderRadius("20vp") 254 .backgroundColor("rgba(24,36,49,0.05)") 255 .onClick(()=>{ 256 this.sendableTask(); 257 }) 258 } 259 } 260 .width("100%") 261 .height("168vp") 262 .position({ x: "0", y: "73%" }) 263 .padding({ left: "25vp", right: "25vp" }) 264 } 265 .width("100%") 266 .height("100%") 267 .justifyContent(FlexAlign.Center) 268 } 269 270 async executeImmediately(): Promise<void> { 271 if (!this.taskPoolInPutStr.length) { 272 this.taskPoolOutPutStr = "No input for the string to be sorted.\n"; 273 return; 274 } 275 let task = new taskpool.Task(strSort,this.taskPoolInPutArr); 276 this.gStack.push(task); 277 try { 278 let result: taskpool.Task = await taskpool.execute(task) as taskpool.Task; 279 this.taskPoolOutPutStr += "Task executed successfully: "+ result.toString()+ "\n"; 280 } catch(e) { 281 this.taskPoolOutPutStr += "Task executed failed: "+ (e as BusinessError).toString()+ "\n"; 282 } 283 this.gStack.pop(); 284 } 285 286 async executeDelay(): Promise<void> { 287 if (!this.taskPoolInPutStr.length) { 288 this.taskPoolOutPutStr = "No input for the string to be sorted.\n"; 289 return; 290 } 291 let task = new taskpool.Task(strSortDelay,this.taskPoolInPutArr); 292 this.gStack.push(task); 293 try { 294 let result: string[] = await taskpool.execute(task) as string[]; 295 this.taskPoolOutPutStr += "Task executed successfully: "+ result.toString()+ "\n"; 296 } catch(e) { 297 this.taskPoolOutPutStr += "Task executed failed: "+ (e as BusinessError).toString() + "\n"; 298 } 299 this.gStack.pop(); 300 } 301 302 async executeFunc(): Promise<void> { 303 if (!this.taskPoolInPutStr.length) { 304 this.taskPoolOutPutStr = "No input for the string to be sorted.\n"; 305 return; 306 } 307 try { 308 let result: string[] = await taskpool.execute(strSort,this.taskPoolInPutArr) as string[]; 309 this.taskPoolOutPutStr += "Task executed successfully: "+ result.toString()+ "\n"; 310 } catch(e) { 311 this.taskPoolOutPutStr += "Task executed failed: "+ (e as BusinessError).toString()+ "\n"; 312 } 313 } 314 315 async taskAdd(): Promise<void> { 316 if (!this.taskPoolInPutStr.length) { 317 this.taskPoolOutPutStr = "No input for the string to be sorted.\n"; 318 return; 319 } 320 try { 321 let task: taskpool.Task = new taskpool.Task(strSort, this.taskPoolInPutArr); 322 this.taskGroup.addTask(task); 323 this.isTaskGroup = true; 324 this.taskPoolOutPutStr += "TaskGroup addTask successfully.\n"; 325 } catch (e) { 326 this.taskPoolOutPutStr += "TaskGroup addTask failed: "+ (e as BusinessError).toString()+ "\n"; 327 } 328 } 329 330 Clear(): void { 331 this.taskPoolInPutStr = ''; 332 this.taskPoolInPutArr = this.taskPoolInPutStr.trim().split(','); 333 this.taskPoolOutPutStr = ''; 334 } 335 336 async TaskGroupExec(): Promise<void> { 337 try { 338 let res: string[] = await taskpool.execute(this.taskGroup) as string[]; 339 this.taskPoolOutPutStr += "TaskGroup executed successfully: "+ res.toString()+ "\n"; 340 } catch(e) { 341 this.taskPoolOutPutStr += "TaskGroup executed failed: "+ (e as BusinessError).toString()+ "\n"; 342 } 343 this.isTaskGroup = false; 344 } 345 346 async cancelTask(): Promise<void> { 347 if (this.gStack.isEmpty()) { 348 this.taskPoolOutPutStr += "The current task queue has no cancellable tasks."+ "\n"; 349 } else { 350 let task: taskpool.Task = this.gStack.peek() as taskpool.Task; 351 try { 352 taskpool.cancel(task); 353 this.taskPoolOutPutStr += "Task canceled successfully."+ "\n"; 354 this.gStack.pop(); 355 } catch(e) { 356 this.taskPoolOutPutStr += "Task canceled failed: "+ (e as BusinessError).toString()+ "\n"; 357 } 358 } 359 } 360 361 async sendableTask(): Promise<void> { 362 // 定义主线程异步锁sendableTask_lock 363 let lock: utils.locks.AsyncLock = utils.locks.AsyncLock.request("sendableTask_lock"); 364 let count: number = 0; 365 lock.lockAsync(async () => { 366 // 主线程调用实例a.data1的方法setCount、getCount 367 a.data1.setCount(111); 368 count = await a.data1.getCount(); 369 console.info("this data1 count is: " + await a.data1.getCount()); 370 }) 371 let task: taskpool.Task = new taskpool.Task(createSendableData, a); 372 try { 373 await taskpool.execute(task); 374 this.taskPoolOutPutStr += "sendableTask execute successfully."+ "\n"; 375 // 访问子线程返回的实例a中的各个属性 376 this.taskPoolOutPutStr += "Sendable data TestA v1 is: " + a.data1.v1 + "\n"; 377 this.taskPoolOutPutStr += "Sendable data TestA v2 is: " + a.data1.v2 + "\n"; 378 this.taskPoolOutPutStr += "Sendable data TestA v3 is: " + a.data1.v3 + "\n"; 379 this.taskPoolOutPutStr += "Sendable data TestA count is: " + count + "\n"; 380 this.taskPoolOutPutStr += "Sendable data TestB v1 length is: " + a.data2.v1.length + "\n"; 381 this.taskPoolOutPutStr += "Sendable data TestB v2 has key: " + a.data2.v2.has(100) + "\n"; 382 this.taskPoolOutPutStr += "Sendable data TestB v3 size is: " + a.data2.v3.size + "\n"; 383 } catch(e) { 384 this.taskPoolOutPutStr += "Task execute failed: "+ (e as BusinessError).toString()+ "\n"; 385 } 386 } 387} 388 389@Concurrent 390function strSort(inPutArr: string[]) : string[] { 391 let newArr: string[] = inPutArr.sort(); 392 return newArr; 393} 394 395@Concurrent 396function strSortDelay(inPutArr: string[]) : string[] { 397 let start: number= new Date().getTime(); 398 while (new Date().getTime() - start < 3000) { 399 continue; 400 } 401 let newArr: string[] = inPutArr.sort(); 402 return newArr; 403} 404 405@Concurrent 406async function createSendableData(data: SendableClass): Promise<void> { 407 // 定义taskpool子线程异步锁sendableTask_lock 408 let lock: utils.locks.AsyncLock = utils.locks.AsyncLock.request("sendableTask_lock"); 409 410 // 构造TestA、TestB实例,组装SendableClass实例 411 let d1: TestA = new TestA(); 412 d1.v1 = 1010; 413 d1.v2 = "aaa"; 414 d1.v3 = true; 415 let d2: TestB = new TestB(); 416 d2.v2.set(100, "aaa"); 417 for(let i = 0;i < 1000;i++) { 418 d2.v1.push(i); 419 } 420 d2.v3.add("hello"); 421 422 lock.lockAsync(async () => { 423 // 子线程调用实例方法setCount、getCount 424 await d1.setCount(10); 425 console.info("taskpool: this data1 count is: " + await d1.getCount()); 426 }) 427 428 data.data1 = d1; 429 data.data2 = d2; 430}