Multithreading 单独线程中的DB连接-什么';这是最好的办法吗?

Multithreading 单独线程中的DB连接-什么';这是最好的办法吗?,multithreading,delphi,delphi-2009,Multithreading,Delphi,Delphi 2009,我正在创建一个访问数据库的应用程序。每次访问数据库时,应用程序都会等待作业完成。 为了保持UI的响应性,我想将所有数据库内容放在一个单独的线程中。 以下是我的想法: db线程在创建时创建它所需的所有数据库组件 现在线程只是坐在那里等待命令 如果收到命令,则执行操作并返回空闲状态。在此期间,主线程将等待 只要应用程序正在运行,db线程就会一直存在 这听起来可以吗? 将数据库结果从db线程导入主线程的最佳方式是什么? 到目前为止,我还没有对线程做太多的工作,因此我想知道db线程是否可以创建一个查

我正在创建一个访问数据库的应用程序。每次访问数据库时,应用程序都会等待作业完成。 为了保持UI的响应性,我想将所有数据库内容放在一个单独的线程中。
以下是我的想法:

  • db线程在创建时创建它所需的所有数据库组件
  • 现在线程只是坐在那里等待命令
  • 如果收到命令,则执行操作并返回空闲状态。在此期间,主线程将等待
  • 只要应用程序正在运行,db线程就会一直存在
这听起来可以吗?
将数据库结果从db线程导入主线程的最佳方式是什么?

到目前为止,我还没有对线程做太多的工作,因此我想知道db线程是否可以创建一个查询组件,主线程从中读取结果。主线程和db线程永远不会同时访问查询。这还会导致问题吗?

我已经实现了两种策略:线程池和临时线程创建

我建议从临时线程创建开始,它更易于实现和扩展

只有在(经过仔细评估)(1)在创建线程时投入了大量资源(和时间)和(2)有大量创建请求时,才能移动到线程池

在这两种情况下,都必须处理传递的参数并收集结果。我建议使用允许此数据传递的属性扩展thread类


请参阅线程使用的类、组件和函数的文档,以确保它们是线程安全的,也就是说,它们可以从不同的线程同时使用。如果没有,则需要同步访问。在某些情况下,您可能会发现关于线程安全性的细微差异。例如,首先请参见DateTimeToStr.

如果您对多线程没有太多经验,请不要从VCL类开始。出于(除其他原因外)以下原因使用:

  • 您的抽象级别是任务,而不是线程,这是处理并发性的更好方法
  • 您可以轻松地在自己的线程中执行任务和使用线程池调度任务之间切换
  • 所有底层细节,如线程关闭、双向通信等,都会为您解决。你可以把注意力集中在数据库上
db线程在创建时创建它所需的所有数据库组件

这可能不是最好的办法。我通常只在需要时创建组件,但不会立即销毁。您一定要在线程池线程中保持连接的打开状态,并且只有在线程处于非活动状态一段时间并且线程池处理了它之后才关闭连接。但是,保存事务和语句对象的缓存通常也是一个好主意

如果收到命令,则执行操作并返回空闲状态。在此期间,主线程将等待

当使用OTL时,第一部分处理得很好。但是,如果不让主线程等待,那么这与直接在VCL线程中执行数据库访问相比没有什么优势。您需要一个异步设计来充分利用多个线程。考虑一个标准数据库浏览器窗体,该窗体具有用于记录记录的控件。每次一个控件发生变化时,我都会(重新)启动一个计时器来处理这个问题。一旦用户完成编辑,就会触发计时器事件(比如500毫秒后),并启动一个任务,该任务将执行根据筛选条件获取数据的语句。网格内容将被清除,并且仅当任务完成时才会重新填充。但这可能需要一些时间,因此VCL线程不会等待任务完成。相反,用户甚至可以再次更改筛选条件,在这种情况下,将取消当前任务并启动新任务。OTL为您提供了一个任务完成事件,因此异步设计很容易实现

将数据库结果从db线程获取到主线程的最佳方法是什么

我通常不为多线程db应用程序使用数据感知组件,而是使用作为业务对象视图的标准控件。在数据库任务中,我创建这些对象,将它们放入列表中,任务完成事件将列表传输到VCL线程

主线程和db线程永远不会同时访问查询


对于所有按需加载数据的组件,您无法确定这一点。通常只从数据库中提取第一条记录,并且在消耗完这些记录后继续提取。这些组件显然不能由线程共享。

您需要的是标准的数据访问技术,称为异步查询执行。一些数据访问组件以易于使用的方式实现此功能。至少dbGo(ADO)和AnyDAC实现了这一点。让我们考虑一下dBGO。< /P> 这个想法很简单——您可以调用方便的数据集方法,就像开放式数据库一样。该方法在后台线程中启动所需任务并立即返回。当任务完成时,将触发一个适当的事件,通知应用程序任务已完成

DB GUI应用程序和开放方法的标准方法如下(草案):

  • 将eoAsyncExecute、eoAsyncFetch、eoAsyncFetchNonBlock包含到数据集执行选项中
  • 断开TDataSource.DataSet与数据集的连接
  • 将dataset OnFetchComplete设置为进程
  • 显示“您好!我们正在努力处理您的请求。请稍候…”对话框
  • 调用dataset Open方法
  • 当查询执行完成时,将调用OnFetchComplete,因此P.和P隐藏“Wait”对话框,并将TDataSource.DataSet连接回数据集
另外,您的“等待”对话框可能有一个取消b