我在线程方面的经验有限。我想要并行读取一些基本数据库表,需要等待所有表格都被读取完毕,然后程序才能合理地继续进行。在这方面,阻塞主线程对我来说是可以接受的。
这段代码(简化版)运行良好:
procedure ReadDBMultiThread;
var ATasks : Array of ITask;
begin
SetLength(ATasks, 3);
ATasks[0] := TTaskCreate(procedure() begin DB_ReadTable1; end);
ATasks[1] := TTaskCreate(procedure() begin DB_ReadTable2; end);
ATasks[2] := TTaskCreate(procedure() begin DB_ReadTable3; end);
ATasks[0].Start;
ATasks[1].Start;
ATasks[2].Start;
TTask.WaitForAll(ATasks);
end;
然而,假设我想更新主表单以显示进度,即已读取哪个数据库表(或执行任何其他必要的主线程工作)。显然,我不能使用Synchronize(),因为那会导致与WaitForAll()死锁;而我也不能使用Queue(),因为那会在WaitForAll()完成后执行。那么,有没有好的解决方案来解决“WaitForAll vs Synchronize”情况?我猜,这一定是许多人遇到的情况……需要等待所有操作都完成,但又想要更新主线程……我考虑了类似于下面的伪代码,替换WaitForAll()语句:
repeat
Applicaton.ProcessMessages; // or "ProcessSynchroniseMessages"
until "AllTaskCompleted"(ATasks);
这样做有用吗?有更好的解决方案吗?
我能自己编写像ProcessMessages一样的例程,但限制在同步消息上,即其他主窗体事件在稍后执行,可以吗?
非常感谢您的帮助!