我试图做一个小闪屏,所以我的程序可以打开查询而不会阻止我的应用程序。 我写的代码就是这个。
procedure TOpenThread.OpenTable;
begin
FActiveTable.NonBlocking := true;
FActiveTable.open;
end;
procedure TOpenThread.AbrirTablas;
begin
FActiveTable := FOwnerPlan.TablasEdicion.Tabla;
Synchronize(OpenTable);
while FActiveTable.Executing do
begin
if Terminated then CancelExecution;
sleep(10);
end;
FActiveTable.NonBlocking := false;
end;
此代码在一个线程中执行,并在主线程被卡住时继续执行
我正在使用delphi 2007
答案 0 :(得分:1)
此代码在线程中执行
现在,它没有。您的代码是:
Synchronize(OpenTable);
这明确表示OpenTable
过程在主VCL线程内和后台辅助TOpenThread
之外执行。
有关Synchronize
的更多详细信息,您可以尝试学习https://stackoverflow.com/a/44162039/976391
总而言之,复杂问题并没有简单的解决方案。
如果要将数据库交互卸载到单独的线程中,则必须使该线程成为所有数据库组件的独占所有者和用户,从数据库连接开始,直至每个事务和每个查询。
然后,您必须使ASYNCHRONOUSLY将数据请求从主VCL线程发布到DB帮助程序线程,并且ASYNCHRONOUSLY从它接收数据包。 OmniThreadLibrary就像数据流一样 - 阅读他们的教程,以便在使用多线程时获得内部程序结构的要点。
您可以尝试按照以下经验法则修改您的应用程序。 它不是最快的多线程,但可能是最简单的。
所有数据库组件的工作都是在TOpenThread.Execute
上下文中完成的,这些组件是TOpenThread
类的本地成员变量。仅在TOpenThread.Execute
内进行连接断开; TOpenThread.Execute
等待来自主线程的命令几乎无限(直到线程终止)和受限制的循环。
将特定数据库请求设为anonymous procedures
,并添加到TThreadedQueue<T>
对象的某个TOpenThread
公共成员中。 .Execute
内的循环尝试从该队列中获取操作并执行它(如果存在),或者如果队列为空则执行限制(Yield()
)。数据库操作不允许使用Synchronize
和Queue
包装器。主VCL线程仅发布请求,但绝不等待它们实际执行。
执行后的那些匿名程序会将数据库结果传回主线程。像http://www.uweraabe.de/Blog/2011/01/30/synchronize-and-queue-with-parameters/或类似Sending data from TThread to main VCL Thread或任何其他回到主线程的方式。
TOpenThread.Execute
标志已设置且队列为空,则 Terminated
仅退出循环。如果设置了Terminated
,那么立即退出将会丢失仍在等待队列未处理的操作。
似乎枯燥乏味但很容易?完全没有,在那里添加你必须拦截异常并以异步方式处理所有错误 - 并且你会“放松”进入这个领域的任何希望&#34;。
PS。并且最后但并非最不重要的是,关于&#34;这个代码在一个线程中执行,并且在主线程被卡住时继续这样做&#34;坦率地说,我猜你在这里错了,我认为你的线程彼此都被困在了一起。
如果没有完全理解线程到线程锁定如何在这个特定的组件中工作,地毯轰炸代码调用Synchronize
和其他线程间锁定工具,你很有可能只追逐它们线程进入相互锁定状态,死锁。见http://stackoverflow.com/questions/34512/