优化多线程加载指示器实现
在ChinaCock框架中,CC.LoadingIndicator组件提供了良好的视觉反馈机制。以往曾撰写过相关使用文档可供参考。
常规使用方式如下所示:
<strong>LoadingDisplay1</strong>.StartIndicator('数据检索中,请等待...');
TaskScheduler.Execute(
procedure (const Event:IkbmMWScheduledEvent)
begin
//后台线程执行数据处理
end)
.ThenInvoke(
procedure (const Event:IkbmMWScheduledEvent)
begin
//任务完成后返回主线程更新UI
<strong>LoadingDisplay1</strong>.StopIndicator;
end)
.OnError(
procedure (const Error:Exception)
begin
<strong>LoadingDisplay1</strong>.StopIndicator;
HandleApplicationError(Error);
end)
.Start;
上述模式通过配对调用StartIndicator和StopIndicator来控制加载提示的显隐状态,确保异步操作结束后能及时关闭提示界面。这种方式在单个并发任务场景下表现良好,但在多个并行任务环境下会出现异常情况。示例如下:
//启动首个异步操作
LoadingDisplay1.StartIndicator('处理首个作业中...');
TaskScheduler.Execute(
procedure (const Event:IkbmMWScheduledEvent)
begin
//执行首项后台工作
end)
.ThenInvoke(
procedure (const Event:IkbmMWScheduledEvent)
begin
LoadingDisplay1.StopIndicator;
end)
.OnError(
procedure (const Error:Exception)
begin
LoadingDisplay1.StopIndicator;
HandleApplicationError(Error);
end)
.Start;
//启动次个异步操作
LoadingDisplay1.StartIndicator('处理次个作业中...');
TaskScheduler.Execute(
procedure (const Event:IkbmMWScheduledEvent)
begin
//执行次项后台工作
end)
.ThenInvoke(
procedure (const Event:IkbmMWScheduledEvent)
begin
LoadingDisplay1.StopIndicator;
end)
.OnError(
procedure (const Error:Exception)
begin
LoadingDisplay1.StopIndicator;
HandleApplicationError(Error);
end)
.Start;
以上代码仅用于演示目的,展示了两项并发任务的启动过程。实际运行时,无论哪项任务率先结束,都会触发StopIndicator方法导致加载提示消失,此时尚未完成的操作仍需显示加载状态,从而引发逻辑冲突。
经过重构后的加载指示器版本已彻底解决这一并发问题。
示例中使用的任务调度基于kbmMW Scheduler Framework框架。相关内容已有翻译资料可供查阅。