如何在工作线程上线程保护ClientDataSet?

时间:2017-09-14 20:06:26

标签: multithreading delphi

我有一个非常慢的查询,总是让Windows将我的程序标记为无响应。我决定创建一个后台工作程序来执行此查询,同时主线程显示GIF。我做了一切,它的工作原理! = D

但是......当我关闭我的表单时,我得到了一个EInvalidPointer异常,仅当我使用工作线程时。

这是我的代码:

主线程调用工作线程

<name of owner>

其中:  cdsSolicitacao是我想要在线程之间共享的clientDataSet,  FConsultaSql字符串(我的查询)

我的线程单位

if not TThreadDB.ExecutarThreadDB(cdsSolicitacao,
                                   FConsultaSql,
                                   nil,
                                   tpHigher) then
 begin
   Exit;
 end;

我缺少什么想法?

1 个答案:

答案 0 :(得分:1)

你没有在你的问题中提到过,但我猜你所描述的问题可能是由于修改了数据集对象引起的,而该数据集对象主要由主线程消耗(例如,在网格中显示)。换句话说,您将传递给工作线程数据集,该数据集链接到主线程中的某些控件。或者,换句话说,您的 cdsSolicitacao 数据集对象通过数据源对象链接到主窗体上的某些控件。

请注意主线程无法使用正在由工作线程修改的对象

即使是模态动画也不会阻止主线程消耗刚刚修改过的数据集。例如,可以请求DB网格进行重绘,这需要访问其底层数据集,同时由工作线程修改。

如果是这种情况,并且您不想创建新的数据集实例,然后在工作线程完成时替换为使用的数据集实例, 你需要(理想情况下)在传递给工作线程之前将数据集对象与每个链接控件断开连接,并在完成时重新连接。