即使NonBlocking设置为true,TOraDataSet也会阻止我的程序

时间:2017-05-31 11:47:43

标签: oracle delphi delphi-2007 odac

我试图做一个小闪屏,所以我的程序可以打开查询而不会阻止我的应用程序。 我写的代码就是这个。

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

1 个答案:

答案 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())。数据库操作不允许使用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,那么立即退出将会丢失仍在等待队列未处理的操作。

似乎枯燥乏味但很容易?完全没有,在那里添加你必须拦截异常并以异步方式处理所有错误 - 并且你会“放松”进入这个领域的任何希望&#34;。

PS。并且最后但并非最不重要的是,关于&#34;这个代码在一个线程中执行,并且在主线程被卡住时继续这样做&#34;坦率地说,我猜你在这里错了,我认为你的线程彼此都被困在了一起。 如果没有完全理解线程到线程锁定如何在这个特定的组件中工作,地毯轰炸代码调用Synchronize和其他线程间锁定工具,你很有可能只追逐它们线程进入相互锁定状态,死锁。见http://stackoverflow.com/questions/34512/