2017-05-31 76 views
-1

我试图做一个小闪屏,所以我的程序可以打开querys withaout挡住了我的aplication。 我写的代码是这样的。TOraDataSet挡住了我的计划,即使非阻塞设置为true

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; 

此代码是在一个线程中执行,并且一直这样做,而主线程被我使用的是2007年德尔福

+0

哪里是主线程阻塞? –

回答

1

此代码是在一个线程中执行stucked

现在

,事实并非如此。您的代码是:

Synchronize(OpenTable); 

这意味着明确OpenTable程序主VCL线程中和你的背景auxillary TOpenThread外执行。在Synchronize

更多的细节,你可以尝试从学习是在https://stackoverflow.com/a/44162039/976391

所有的一切,还有就是解决复杂问题没有简单的解决方案。

如果你想卸载数据库交互转化为一个单独的线程,你将不得不作出从一DB连接以及高达每一笔交易和每一个查询开始的所有DB组件的线程独家所有者和用户。

然后,您将不得不做出异步方式将数据请求从主VCL线程发布到DB助手线程,并异步接收来自它的数据包。 OmniThreadLibrary就像数据流一样 - 阅读他们的教程以获得使用多线程时内部程序结构的要点。

您可以尝试修改应用程序,以拇指以下规则。 它不会是最快的多线程,但也许是最简单的。

  • 所有数据库组件的工作是完全内部TOpenThread.Execute上下文中完成,并且那些部件的本地成员变量的TOpenThread类。连接断开仅在TOpenThread.Execute内进行; TOpenThread.Execute等待来自主线程在几乎无限的命令(直到该线程被终止)和节流环。

  • 特定数据库请求作为anonymous procedures作出,并被添加到TOpenThread对象的某些TThreadedQueue<T>公共成员。内部.Execute环路试图获取从该队列中的动作并执行它,如果存在,或者油门(Yield())如果队列是空的。数据库操作周围不允许有SynchronizeQueue包装。主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设置然后立即退出将失去行动仍然在等待队列中未处理。

似乎枯燥而乏味,但容易吗?根本不是,增加那里,你将不得不拦截异常和处理在异步方式,所有的错误 - 你会“失去进入这一领域的任何希望”。

PS。最后但并非最不重要的,关于“此代码是在一个线程中执行,并且一直这样做,而主线程被stucked”假设,坦率地说,我想你是错在这里,我认为无论是你的线程是由彼此卡住。 没有完全理解螺纹与螺纹的锁固是如何设计在这个特定组件的工作,地毯式轰炸与调用代码Synchronize和其它线程间锁定工具,你有相当多的机会,只是追逐他们所有的线程注入互锁状态,僵局。见http://stackoverflow.com/questions/34512/

+0

是的,但该数据集的“非阻塞”属性应该让它执行主线程 –

+1

没有,OpenTable'在主线程中执行的方法'之外。如果没有 - 那么没有理由与创建'TOpenThread'打扰 - 只是叫'从你的主线程代码.OpenTable'!现在的问题是,一些活动(但不是全部!)没有更多的内'OpenTable'执行,但下车加载通过其他方法来执行。我不确定。然而,确实是这样的:'Synchronize'正在消除它的参数的多线程,这就是那个调用被引入的原因。 –