- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对线程的经验有限。我想并行读取一些基本的数据库表,我需要等到所有表都读取完,程序才能合理地进行。在这方面,阻塞主线程对我来说没问题。
此代码(简化版)工作正常:
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;
但是,假设我想更新主窗体以显示进度,即哪个数据库表已被读取(或执行任何其他必要的主线程工作)。显然,我不能使用 Synchronise(),因为这会导致 WaitForall() 的死锁,而且我不能使用 Queue(),因为它会在 WaitForAll() 完成后执行。
那么,有没有什么好的方案可以解决这种“WaitForAll vs Synchronise”的情况呢?我想,这一定是很多人遇到的情况……需要等待全部完成,但又想更新主线程……
我想到了这样的事情,用伪代码给出,替换了 WaitForAll() 语句:
repeat
Applicaton.ProcessMessages; // or "ProcessSynchroniseMessages"
until "AllTaskCompleted"(ATasks);
这行得通吗?有更好的解决方案吗?
我是否可以编写一个自己的例程,如 ProcessMessages,但仅限于同步消息,即其他主要表单事件直到稍后才会执行?
非常感谢!
最佳答案
TThread.Synchronize()
和 TThread.Queue()
不使用窗口消息(好吧,有一个消息“唤醒”主线程来发出信号挂起的请求,但实际同步本身不是基于消息的)。请求被放入一个全局队列中,主线程在空闲时或检测到“唤醒”消息时检查该队列。您可以通过直接调用 Classes.CheckSynchronize()
函数手动抽取同一个队列:
while not TTask.WaitForAll(ATasks, 1000) do
begin
// process any pending TThread.Synchronize() and TThread.Queue() requests
CheckSynchronize(0);
// process any pending UI paint requests, but not other messages
Application.MainForm.Update;
// anything else you need...
end;
关于multithreading - Delphi TTask WaitForAll 与同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31999429/
单击按钮后,我创建 3 个任务,每个任务都有空过程,并将方法调用和任务列表完成的时间差写入控制台: procedure TWinTest.BtnThreadTestClick(Sender: TObj
根据我阅读 Nick Hodges 的理解,这段代码应该没问题: TTask.Run( procedure var resp, tmp: string; req: boolea
专家,请看下面的代码片段: var aAllTasks : Array [0..1] of ITask //global private var Procedure SetImage(); be
我不知道如何在 Delphi 中正确使用 TTask。 我创建了一个 TTask。 syncTask := ttask.Create(SyncMysqlDatabase); 以下代码在onlocati
我对线程的经验有限。我想并行读取一些基本的数据库表,我需要等到所有表都读取完,程序才能合理地进行。在这方面,阻塞主线程对我来说没问题。 此代码(简化版)工作正常: procedure ReadDBMu
我有以下两种多线程代码方法来完成相同的工作。 任务: const MaxThreadCount = 80; procedure TWorkerTask.Update; var aTasks
Delphi 中的匿名方法创建一个闭包,该闭包在上下文中保持“包围”局部变量,直到匿名方法完成。如果使用接口(interface)变量,那么它们将在匿名方法完成之前减少其引用的实例。到目前为止一切顺利
背景 使用 TThread.CreateANonymousThread(aProc:TProc)我可以创建一个线程,在线程终止后销毁线程对象。 (或者将 FreeOnTerminate 设置为 tru
这是我在 DLL 中的代码: procedure TTaskTest; begin TTask.Run( procedure begin Sleep(300);
我是一名优秀的程序员,十分优秀!