繁体   English   中英

TDataset与DBGrid的线程竞赛

[英]TDataset thread races with DBGrid

我使TDataset后代成为异步的,而不是主线程中的sleepProcessMessages ,它由网络线程中的事件起作用。 因此,当Recordset准备就绪时,它将调用

procedure TMySqlQuery.OrdinalOnDataReady(Sender: TObject);
begin
  AddToLog('OrdinalOnDataReady');
  FDataAvailable := true; // used in IsCursorOpen
  inherited Open;
  if Assigned(FParentOnDataReady) then
      FParentOnDataReady(self);
end;

它的工作原理,但有时我有问题GetRecord通过Open从这个线程和DBGrid中的所谓GetFieldData通过的DBGrid实现主营线程调用DrawCells从窗体的ProcessMessages。 通过记录两个功能,我看到了

[17:10:39] RecordToBuffer row 0
[17:10:39] len = 17 buf : 
00 E0 10 C3 00 0A 00 00 00 F0 10 C3 00 0B 00 00   |  .ïœ.ï“.....ÿ€.ï“....
00   |  .
[17:10:40] RecordToBuffer row 1
[17:10:40] len = 17 buf : 
00 00 FF C3 00 25 00 00 00 10 11 C3 00 0B 00 00   |  ..ÿï“.%.....ï“....
00   |  .
[17:10:40] ActiveBuffer
[17:10:40] len = 17 buf : 
00 E0 10 C3 00 0A 00 00 00 F0 10 C3 00 0B 00 00   |  .ïœ.ï“.....ÿ€.ï“....
00   |  .
...
more ActiveBuffer
...
[17:10:40] ActiveBuffer
[17:10:40] len = 17 buf : 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |  ................
00   |  .
[17:10:40] len = 8 buf : 
00 00 00 00 00 00 00 00   |  ........

当ActiveBuffer列数据为nil时断言,我可以看到DBGrid尝试读取的行比读取到自己内部FBuffers中的GetRecord高。 例如,如果在GetFieldData第3行触发断言-FBuffers从Recordset中可用的总共36行填充到第2行。 当我用F8逐步调试GetRecord ,没有错误,我按F9并在另一条记录中声明。

我不太了解DBGrid如何与TDataset一起TDataset (即使堆栈跟踪很大),但是可以解决此线程TDataset用问题吗?

解决方案非常简单:由于TDataset的FBuffers中的数据(来自Data.DB)如果未初始化则填充为0,因此可以通过GetRecord查找填充的ActiveBuffer,也可以通过在记录中添加另一个标记字节并在GetRecord中不分配0来找到。 因此,如果DBGrid尝试读取未初始化的数据,我将检查GetFieldData中的标记,如果0结果为false并退出。 由于DBGrid多次将数据提取到相同的单元格中,因此我仍然用适当的数据填充了该数据。 这是解决方法,但可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM