我使 TDataset 后代异步,而不是sleep
在ProcessMessages
主线程中,它通过来自网络线程的事件工作。因此,当 Recordset 准备就绪时,它会调用
procedure TMySqlQuery.OrdinalOnDataReady(Sender: TObject);
begin
AddToLog('OrdinalOnDataReady');
FDataAvailable := true; // used in IsCursorOpen
inherited Open;
if Assigned(FParentOnDataReady) then
FParentOnDataReady(self);
end;
它可以工作,但有时我会遇到从这个线程调用的问题,而GetRecord
DBGrid从 Form 的 ProcessMessages调用的 DBGrid 从主线程调用。通过记录我看到的两个功能Open
GetFieldData
DrawCells
[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 从 Recordset 中可用的总共 36 行中填充到第 2 行。当我使用 F8 逐步调试时,GetRecord
没有错误,我按 F9 并在另一条记录中获得断言。
我不太明白究竟是如何DBGrid
工作的TDataset
(即使堆栈跟踪很大),但是这个线程竞争可以解决吗?