Несколько лет назад для одного из моих приложений я переместил свою последовательную обработку в поток, когда определенное приложение должно было очень быстро реагировать на определенные последовательные события.
Это было в 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
Я провел быстрое тестирование с новейшей версией и произвел необходимую перестановку (функция уничтожения строк используется для двоичного протокола). Я застрял на некоторое время, потому что приложение зависало при запуске, но это потому, что я использую gnugettext, а Comport упаковывает другую (не unicode даже?) Версию. Но после этого работает .
К сожалению, изменения немного рискованны для распространения обратно в рабочую версию (полностью написанное декодирование протокола), поэтому мне придется протестировать промежуточные версии (между 4.0 и 4.11f). Я сделаю это в свое время, какие-нибудь предложения, какая версия была последней readstr (ansistring)?
Обновление 3
В конце я просто переименовал блоки 4.11f и использую их параллельно старой версии, используя 4.11f для многопоточных кодовых баз и старую для поддержки существующего кода.
В долгосрочной перспективе я мог бы просто взять код ожидания и сделать собственную версию. Основная проблема заключается в том, что на самом деле невозможно увидеть, закончилось ли ожидание по тайм-ауту, остановке или тому подобному. Это означает, что вам нужен еще один таймер, если вы хотите, например, отправлять с регулярными интервалами.