首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TDataset线程与DBGrid的竞争

TDataset线程与DBGrid的竞争
EN

Stack Overflow用户
提问于 2014-01-11 15:52:15
回答 1查看 362关注 0票数 0

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

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

它可以工作,但有时我会遇到GetRecord的问题,Open从这个线程调用Open,而DBGrid的GetFieldData从主线程调用DBGrid的DrawCells从表单的ProcessMessages调用。通过记录这两个函数,我看到

代码语言:javascript
复制
[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列数据为零时,在按断言断续时,我可以看到DBGrid试图读取比GetRecord更高的行到自己的内部FBuffers中。例如,如果在GetFieldData上激发的断言,第3行- FBuffers从记录集中可用的36行填充到第2行。当我一步一步地用GetRecord调试F8时,没有错误,utnil,我按下F9,并在另一个记录中获得断言。

我不太明白DBGrid是如何与TDataset一起工作的(即使堆栈跟踪也是巨大的),但是这个线程竞赛可以解决吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-12 13:58:53

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21064363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档