Я сделал TDataset потомком асинхронным, а не sleep
или ProcessMessages
в основном потоке он работает событиями из сетевой нити. Поэтому, когда Recordset готов он называет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-х 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 равна нулю, можно видеть, что DBGrid пытается прочитать строку выше, чем GetRecord
прочтенных в собственные внутренние FBuffers. Например, если утверждение было начато с GetFieldData
, строка 3 - FBuffers, заполненная до строки 2 из 36 строк, доступных в наборе записей. Когда я отлаживаю шаг за шагом GetRecord
с F8, нет ошибок utnil Я нажимаю F9 и получаю утверждение в другой записи.
Я не совсем понимаю, как именно DBGrid
работает с TDataset
(даже трассировка стека огромна), но можно ли решить эту цепочку?
Доступ к TDataSet из двух потоков одновременно не допускается. TDataSet не является потокобезопасным. –
У Джоанны Картер был хороший набор статей о внутренностях TDataSet. Может быть, вы все еще можете их найти где-то .... Что я помню из своего опыта Delphi 5 с TDbf, элементы управления, поддерживающие db, заботятся только о количестве буферов, поэтому, если вы, например, сообщили, что у вас есть 10 для подсчета буферов - контроль свободен читать их все. Если ваши буферы не готовы - тогда не сообщайте, что у вас есть десять буферов. –
@ Arioch'The - и где статья Joannas? – Branko