Hol*_*rwa 4 delphi multithreading delphi-2009
我正在创建一个访问数据库的应用程序.在每次访问数据库时,应用程序都会等待作业完成.为了保持UI响应,我想将所有数据库内容放在一个单独的线程中.
这是我的想法:
听起来不错吗?
将数据库结果从db-thread导入主线程的最佳方法是什么?
到目前为止,我对线程做的并不多,因此我想知道db-thread是否可以创建一个查询组件,主线程读取结果.主线程和数据库线程永远不会同时访问查询.这还会导致问题吗?
您正在寻找的是标准数据访问技术,称为异步查询执行.一些数据访问组件以易于使用的方式实现此功能.至少dbGo(ADO)和AnyDAC实现了这一点.让我们考虑一下dbGo.
这个想法很简单 - 你可以调用方便的数据集方法,比如Open.该方法在后台线程中启动所需任务并立即返回.任务完成后,将触发相应的事件,通知应用程序任务已完成.
使用DB GUI应用程序和Open方法的标准方法如下(草稿):
此外,您的"等待"对话框可能有一个取消按钮,用户可以使用该按钮取消运行时间过长的查询.
首先 - 如果您没有多线程经验,请不要从VCL类开始.使用OmniThreadLibrary,以及(其中包括)这些原因:
db-thread在创建时创建所需的所有数据库组件
这可能不是最好的方法.我通常只在需要时才创建组件,但不会立即销毁.您绝对应该在线程池线程中保持连接打开,并且只有在线程处于非活动状态一段时间后才关闭它,并且池会处理它.但是保留事务和语句对象的缓存通常也是一个好主意.
如果它收到命令,它将执行操作并返回空闲状态.在此期间主线程等待.
第一部分在使用OTL时处理得很好.但是 - 没有主线程等待,这将比首先直接在VCL线程中执行数据库访问带来一点优势.您需要异步设计才能充分利用多个线程.考虑一个标准数据库浏览器表单,它具有过滤记录的控件.每当其中一个控件发生变化时,我会通过(重新)启动计时器来处理这个问题.一旦用户完成编辑定时器事件触发(例如在500毫秒之后),就会启动一个任务,执行根据过滤条件获取数据的语句.网格内容被清除,只有在任务完成后才会重新填充.这可能需要一些时间,因此VCL线程不会等待任务完成.相反,用户甚至可以再次更改过滤条件,在这种情况下,当前任务被取消并且新的任务开始.OTL为您提供完成任务的事件,因此异步设计很容易实现.
将数据库结果从db-thread导入主线程的最佳方法是什么?
我通常不会将数据感知组件用于多线程数据库应用程序,而是使用标准控件作为业务对象的视图.在数据库任务中,我创建这些对象,将它们放入列表中,任务完成事件将列表传输到VCL线程.
主线程和数据库线程永远不会同时访问查询.
对于按需加载数据的所有组件,您无法确定这一点.通常只从db中获取第一个记录,并且在消耗之后继续提取.这些组件显然不能被线程共享.