簡體   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