Использование событий в компоненте последовательного порта 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

Теперь реальные вопросы:

  1. у кого-нибудь есть tcomport4, работающий в потоке?
  2. Есть ли очевидные ошибки в вышесказанном?
  3. или мне нужно перейти на другой компонент?

Я все еще отлаживаю то, что происходит, но спешу, пока я публикую это в надежде быстро получить указатели.

Обновить

Я переустановил старую копию 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 для многопоточных кодовых баз и старую для поддержки существующего кода.

В долгосрочной перспективе я мог бы просто взять код ожидания и сделать собственную версию. Основная проблема заключается в том, что на самом деле невозможно увидеть, закончилось ли ожидание по тайм-ауту, остановке или тому подобному. Это означает, что вам нужен другой таймер, если вы хотите, например, отправлять через регулярные интервалы.

1 ответ

Решение

Вы должны обновить до последней стабильной версии 4.11 здесь.

Другие вопросы по тегам