Использование событий в компоненте последовательного порта TComPort (v4) из потока в Delphi?
Несколько лет назад для одного из моих приложений я переместил свою последовательную обработку в поток, когда определенное приложение должно было очень быстро реагировать на определенные последовательные события.
Это было в BDS2006, с более старой версией (около 3.x?). Это было сделано с помощью следующего кода в tthread.execute:
while ...
begin
events:=[evRxChar];
{ Prepare a stop event for killing a waiting communication wait. }
try
comport1.WaitForEvent(events,stopevent.handle,500);
if evRxChar in events then
ComPort1RxChar(comport1,comport1.InputCount); // method of thread.
on e: exception do {only logs} ;
end;
Инициализация была как
procedure TSerThread.initcomport(comportname:string='COM1');
begin
comport1:=tcomport.create(nil);
ComPort1.BaudRate:=br115200;
ComPort1.DataBits:=dbEight;
ComPort1.Port:=comportname;
ComPort1.StopBits:=sbOneStopBit;
ComPort1.Events:=[];
ComPort1.Connected:=true;
StopEvent := TEvent.Create(nil,{ManualReset}false,{InitialState}false,'StopEvent');
end;
Метод rxchar читает с использованием comport1.readstr()
Я недавно должен был выкопать это, и заметил, что это не работает в моем Delphi XE, который имеет tcomport4. Просматривая источник, я заметил, что comport4 изменил способ работы со своими внутренними потоками (свойство "overlapped"), но по умолчанию кажется, что "true" содержит комментарий "classic", и я
Предполагается, что это означает совместимость со старыми версиями.
Обратите внимание, что протоколы являются двоичными, и все строковые, char<-> ansistring, ansichar изменения были сделаны, как я делал в обычной версии mainthread
Теперь реальные вопросы:
- у кого-нибудь есть tcomport4, работающий в потоке?
- Есть ли очевидные ошибки в вышесказанном?
- или мне нужно перейти на другой компонент?
Я все еще отлаживаю то, что происходит, но спешу, пока я публикую это в надежде быстро получить указатели.
Обновить
Я переустановил старую копию Turbo Delphi и убедился, что она работает там с v3. Я исправил небольшую ошибку в пути кода, которая немного отличалась от того, что я думал (не в приведенном выше коде)
Это позволяет мне лучше описать поведение между dxe / comportv4 и bds2006/comportv3; код v4 генерирует гораздо больше событий чтения (сотни / секунду). Кажется, что чтение не удаляет символы чтения из входящей очереди или около того.
Обновление 2
Я провел быстрый тест с новейшей версией и произвел необходимую перестановку (использование функции kill string для по существу двоичного протокола). Я застрял на некоторое время, потому что приложение зависало при запуске, но это потому, что я использую gnugettext, а Comport упаковывает другую (не unicode даже?) Версию. Но после этого это работает.
К сожалению, изменения немного рискованны для распространения обратно в рабочую версию (полностью написанное декодирование протокола), поэтому мне придется протестировать промежуточные версии (между 4.0 и 4.11f). Я сделаю это в свое время, какие-нибудь предложения, какая версия была последней readstr(ansistring)?
Обновление 3
В конце я просто переименовал блоки 4.11f и использую их параллельно старой версии, используя 4.11f для многопоточных кодовых баз и старую для поддержки существующего кода.
В долгосрочной перспективе я мог бы просто взять код ожидания и сделать собственную версию. Основная проблема заключается в том, что на самом деле невозможно увидеть, закончилось ли ожидание по тайм-ауту, остановке или тому подобному. Это означает, что вам нужен другой таймер, если вы хотите, например, отправлять через регулярные интервалы.