HarmonyOS 鸿蒙Next基于Taskpool的多线程操作
HarmonyOS 鸿蒙Next基于Taskpool的多线程操作
HarmonyOS的社区里有很多技术大牛分享经验,学到了很多有用的知识。
场景描述
场景一:周期性任务处理,业务通过taskpool周期性处理业务。
场景二:延迟业务处理,业务一段时间后,通过taskpool处理业务。
场景三:串行业务处理,业务开展过程中,需要处理一系列的事务,事务处理过程中,存在先后次序。
场景四:业务的处理存在紧急优先次序,支持设置taskpool优先级处理。
场景五:ArkTS与Native协作开展业务,在ArkTS层触发业务,通过NAPI接口,传递到Native C++层,作业务管理等处理。
方案描述
场景一:周期性任务
方案:
1)定时器判断周期性事务执行。
2)Taskpool来处理任务执行。
核心代码:
[@Concurrent](/user/Concurrent)
function ServiceHandle(pars: number): number {
hilog.info(0x0000, ‘testTag’, ‘start ServiceHandle:%{public}d’, pars);
// 业务处理过程,并将结果返回
let result = 0;
return result;
}
let count = 0;
function TimerOutHandle(pars:number)
{
count++;
let task: taskpool.Task = new taskpool.Task(ServiceHandle, pars);
hilog.info(0x0000, ‘testTag’, ‘Timer handle count :%{public}d,pars %{public}d’, count, pars);
taskpool.execute(task, taskpool.Priority.HIGH).then((res: object) => {
hilog.info(0x0000, ‘testTag’, ‘ServiceHandle result :%{public}d’, res);
if (g_callback != null) {
g_callback(count);
}
});
}
let timerId = -1;
export function TimerTest()
{
count = 0;
let value = 88;
timerId = setInterval(TimerOutHandle, 3000, value);
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
定时器每3秒超时一次,进入TimerOutHandle函数处理,TimerOutHandle函数体中,通过taskpool创建异步并发任务执行业务。
运行结果:
界面上,每超时一次,会呈现运行次数:
场景二:延迟任务
方案:
1)通过setTimeout来延迟处理。
2) 通过executeDelayed来延迟处理。
核心代码:
1)setTimeout的处理如下:
@Concurrent
function ServiceHandle(pars: number): number {
hilog.info(0x0000, ‘testTag’, ‘start ServiceHandle:%{public}d’, pars);
// 业务处理过程,并将结果返回
let result = 0;
return result;
}
let count = 0;
function TimerOutHandle(pars:number)
{
count++;
let task: taskpool.Task = new taskpool.Task(ServiceHandle, pars);
hilog.info(0x0000, ‘testTag’, ‘Timer handle count :%{public}d,pars %{public}d’, count, pars);
taskpool.execute(task, taskpool.Priority.HIGH).then((res: object) => {
hilog.info(0x0000, ‘testTag’, ‘ServiceHandle result :%{public}d’, res);
if (g_callback != null) {
g_callback(count);
}
});
}
export function OneTimerCallTest()
{
count = 0;
if (g_callback != null) {
g_callback(count);
}
let value = 99;
hilog.info(0x0000, ‘testTag’, ‘start setTimeout’);
timerId = setTimeout(TimerOutHandle, 3000, value);
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
定时器3秒超时(仅仅执行一次)后,就会进入TimerOutHandle函数处理,TimerOutHandle函数体中,通过taskpool创建异步并发任务执行业务。
2)executeDelayed来延迟
@Concurrent
function TaskDelayServiceHandle(pars: number): number {
let t: number = Date.now();
hilog.info(0x0000, ‘testTag’, ‘enter TaskDelayServiceHandle, timer is :%{public}d’, t);
// 业务处理过程,并将结果返回
let result = 0;
return result;
}
export function TaskPoolDelayTest()
{
count = 0;
if (g_callback != null) {
g_callback(count);
}
let value = 100;
let t: number = Date.now();
hilog.info(0x0000, ‘testTag’, ‘taskpool start time is :%{public}d’, t);
let task: taskpool.Task = new taskpool.Task(TaskDelayServiceHandle, value);
taskpool.executeDelayed(3000, task).then(() => {
count++;
let t: number = Date.now();
hilog.info(0x0000, ‘testTag’, ‘taskpool execute success, time is :%{public}d’, t);
if (g_callback != null) {
g_callback(count);
}
}).catch((e: BusinessError) => {
console.error(taskpool execute: Code: ${e.code}, message: ${e.message}
);
})
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
调用executeDelayed函数3秒后,会进入TaskDelayServiceHandle函数执行,返回返回后,会进入executeDelayed后面的then的函数体中执行。
运行结果:
1)使用setTimeout运行结果
2)使用executeDelayed运行结果
场景三:串行任务
方案:
1)最简单的方案就是后面任务执行时,根据前面任务的执行结果来处理。
2)后面任务的执行,依赖另一个任务的一些处理结果后,继续执行。
核心代码:
1)通过业务逻辑的结果来处理
@Concurrent
function ServiceHandle1(pars: number): number {
hilog.info(0x0000, ‘testTag’, ‘start ServiceHandle1:%{public}d’, pars);
// 业务处理过程,并将结果返回
let result = 0;
return result;
}
function ServiceHandle2(pars: number): number {
hilog.info(0x0000, ‘testTag’, ‘start ServiceHandle2:%{public}d’, pars);
// 业务处理过程,并将结果返回
let result = 1;
return result;
}
export function SyncHandle()
{
let task1: taskpool.Task = new taskpool.Task(ServiceHandle1, 1);
hilog.info(0x0000, ‘testTag’, ‘sync handle’);
taskpool.execute(task1, taskpool.Priority.HIGH).then((res1: object) => {
hilog.info(0x0000, ‘testTag’, ‘ServiceHandle result :%{public}d’, res1);
if (g_callback != null) {
g_callback(‘task1 finish.’);
}
if ((res1 as Number) == 0) {
let task2: taskpool.Task = new taskpool.Task(ServiceHandle2, 2);
taskpool.execute(task2, taskpool.Priority.HIGH).then((res2: object) => {
hilog.info(0x0000, ‘testTag’, ‘ServiceHandle2 result :%{public}d’, res2);
if (g_callback != null) {
g_callback(‘task2 finish.’);
}
});
}
});
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
task1执行完毕后,根据if判断启动task2任务执行。
2)通过addDependency或SequenceRunner处理。
@Concurrent
function DependencyHandle(args: number): number {
let t: number = Date.now();
while ((Date.now() - t) < 1000) {
continue;
}
return args;
}
export function AddDependencyTest()
{
let task1:taskpool.Task = new taskpool.Task(DependencyHandle, 100);
let task2:taskpool.Task = new taskpool.Task(DependencyHandle, 200);
let task3:taskpool.Task = new taskpool.Task(DependencyHandle, 300);
hilog.info(0x0000, ‘testTag’, ‘dependency: add dependency start’);
task1.addDependency(task2);
task2.addDependency(task3);
hilog.info(0x0000, ‘testTag’, ‘dependency: add dependency end’);
hilog.info(0x0000, ‘testTag’, ‘dependency: start execute second’);
taskpool.execute(task1).then(() => {
hilog.info(0x0000, ‘testTag’, ‘dependency: first task1 success’);
if (g_callback != null) {
g_callback(‘task1 finish.’);
}
})
taskpool.execute(task2).then(() => {
hilog.info(0x0000, ‘testTag’, ‘dependency: second task2 success’);
if (g_callback != null) {
g_callback(‘task2 finish.’);
}
})
taskpool.execute(task3).then(() => {
hilog.info(0x0000, ‘testTag’, ‘dependency: third task3 success’);
if (g_callback != null) {
g_callback(‘task3 finish.’);
}
})
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
task1依赖task2,task2依赖task3,上面任务执行的顺序是:task3执行完毕后再执行task2,最后执行task。
@Concurrent
function additionDelay(delay:number): void {
let start: number = new Date().getTime();
while (new Date().getTime() - start < delay) {
continue;
}
}
function waitForRunner(finalString: string): string {
return finalString;
}
export async function SeqRunnerTest()
{
let finalString:string = “”;
let task1:taskpool.Task = new taskpool.Task(additionDelay, 3000);
let task2:taskpool.Task = new taskpool.Task(additionDelay, 2000);
let task3:taskpool.Task = new taskpool.Task(additionDelay, 1000);
let task4:taskpool.Task = new taskpool.Task(waitForRunner, finalString);
let runner:taskpool.SequenceRunner = new taskpool.SequenceRunner();
runner.execute(task1).then(() => {
finalString += ‘task1 finish.’;
hilog.info(0x0000, ‘testTag’, ‘seqrunner: task1 done.’);
if (g_callback != null) {
g_callback(‘task1 finish.’);
}
});
runner.execute(task2).then(() => {
finalString += ‘task2 finish.’;
hilog.info(0x0000, ‘testTag’, ‘seqrunner: task2 done.’);
if (g_callback != null) {
g_callback(‘task2 finish.’);
}
});
runner.execute(task3).then(() => {
finalString += ‘task3 finish.’;
hilog.info(0x0000, ‘testTag’, ‘seqrunner: task3 done.’);
if (g_callback != null) {
g_callback(‘task3 finish.’);
}
});
await runner.execute(task4);
hilog.info(0x0000, ‘testTag’, ‘seqrunner: task4 done, finalString is %{public}s’, finalString);
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
task1执行完毕后,执行task2,最后是task3执行完毕。
运行结果:
1)通过业务逻辑的结果来处理
2)通过addDependency或SequenceRunner处理
场景四:优先级任务
方案:
在taskpool.execute的参数二种设置线程的优先级,优先级分三个级别:LOW、MEDIUM(默认)、HIGH。通过设置优先级来运行taskpool任务。
核心代码:
@Concurrent
function ServiceHandle(pri: string): string {
hilog.info(0x0000, ‘testTag’, ‘enter ServiceHandle:%{public}s’, pri);
hilog.info(0x0000, ‘testTag’, ‘end ServiceHandle:%{public}s’, pri);
return pri;
}
export function CallPriorityHanel()
{
let task1: taskpool.Task = new taskpool.Task(ServiceHandle, “LOW”);
let task2: taskpool.Task = new taskpool.Task(ServiceHandle, “MEDIUM”);
let task3: taskpool.Task = new taskpool.Task(ServiceHandle, “HIGH”);
taskpool.execute(task1, taskpool.Priority.LOW).then((res: object) => {
hilog.info(0x0000, ‘testTag’, ‘task return result :%{public}s’, res);
});
taskpool.execute(task2, taskpool.Priority.MEDIUM).then((res: object) => {
hilog.info(0x0000, ‘testTag’, ‘task return result :%{public}s’, res);
});
taskpool.execute(task3, taskpool.Priority.HIGH).then((res: object) => {
hilog.info(0x0000, ‘testTag’, ‘task return result :%{public}s’, res);
});
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
当前的设备都是多核的,并不是说将优先级设置程HIGH,该任务就会最先调度。
运行结果:
场景五:taskpool的Napi调用
方案:C++层编译的库,在ArkTS层通过import库的方式引用后,在taskpool的回调函数中调用接口。核心代码:
@Concurrent
function ServiceHandle(pars: number): number {
hilog.info(0x0000, ‘testTag’, ‘start ServiceHandle:%{public}d’, pars);
// 业务处理过程,并将结果返回
testNapi.jsServiceHandle(88, 99);
return 0;
}
export function CallHandle()
{
let task: taskpool.Task = new taskpool.Task(ServiceHandle, 1);
taskpool.execute(task,).then((res: object) => {
hilog.info(0x0000, ‘testTag’, ‘printArgs result :%{public}d’, res);
});
}
typedef struct TestData {
int data;
int type;
} TestData;
static napi_value JsServiceHandle(napi_env env, napi_callback_info info)
{
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
TestData testData;
napi_get_value_int32(env, args[0], &testData.data);
napi_get_value_int32(env, args[1], &testData.type);
OH_LOG_INFO(LOG_APP, “Native C++ Service handle:%{public}d,type:%{public}d”, testData.data, testData.type);
return nullptr;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
{“jsServiceHandle”, nullptr, JsServiceHandle, nullptr, nullptr, nullptr, napi_default, nullptr}
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
运行结果:
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
您好,当前技术文章配套的demo工程正在外发中,后续会发布至gitee上,敬请关注!
您好,当前技术文章配套的demo工程正在外发中,后续会发布至gitee上,敬请关注!
taskPool是一个全局的线程池吗,所有任务都往这一个池子里面放吗?
假设项目里面有个任务是开启大文件下载,另外一个任务是处理一些耗时操作,两个任务都放在taskPool吗
HarmonyOS 鸿蒙系统中的多线程操作通过TaskPool(任务池)机制来实现高效的并发执行。TaskPool能够管理多个任务的执行,自动分配系统资源,优化任务执行顺序。在HarmonyOS开发中,你可以利用TaskDispatcher或相关API来创建和管理TaskPool。通过向TaskPool提交任务(Runnable或Callable),系统会在后台线程池中异步执行这些任务,而不会阻塞主线程。这对于提升应用性能和响应速度至关重要。如果问题依旧没法解决请加我微信,我的微信是itying888。