我使TDataset後裔異步,而不是sleep
或ProcessMessages
在主線程中它通過來自網絡線程的事件工作。因此,當記錄就緒時,它調用TDataset與DBGrid的線程競賽
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中的DrawCells
從窗體的ProcessMessages從主線程中調用的DBGrid的GetFieldData
。通過登錄這兩個功能我看
[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
readed進入自己的內部FBuffers更高。例如,如果斷言在GetFieldData
第3行觸發 - FBuffers從Recordset中可用的總共36行填充到第2行。當我用F8逐步調試GetRecord
時,沒有錯誤utnil,我按下F9鍵並斷言另一條記錄。
我不太明白DBGrid
與TDataset
(甚至堆棧跟蹤是巨大的)是如何工作的,但是可以解決這個線程競爭嗎?
不允許同時從兩個線程訪問TDataSet。 TDataSet不是線程安全的。 –
喬安娜卡特有一組關於TDataSet內部的文章。也許你仍然可以在某處找到它們......對於我從使用TDbf的Delphi 5體驗中所記得的內容,db-aware控件只關心緩衝區的數量,例如,如果你報告你有10個緩衝區數量 - 控制是可以自由閱讀的。如果你的緩衝區沒有準備好 - 那麼不要報告你有10個緩衝區。 –
@ Arioch'The - Joannas的文章在哪裏? – Branko