Мы можем сделать вывод, что событие VaComm1RXchar
является синхронным событием и что, блокируя вашу программу в цикле, вы предотвращаете обычную обработку сообщений, которая позволила бы этому событию выполнить.
С другой стороны, показ модального диалогового окна передает обработку сообщений этому диалоговому окну, поэтому очередь сообщений правильно обслуживается, а ваши события Rx и обрабатываются нормально.
Вы можете быть уверены, что это в случае, если это работает (пожалуйста, никогда не писать код, как это - это просто, чтобы доказать точку):
while MsgIndex < 1 do begin
stop := GetTickCount;
if (stop - start)> timeout then begin
MessageBox(0, 'Timeout komunikace !', 'Komunikace', MB_OK);
exit(false);
end;
Application.ProcessMessages; // service the message queue so that
sleep(10); // your Rx event can be handled
end;
Если есть урок здесь в том, что RS- 232 действительно нужно делать на фоновом потоке. Большинство реализаций событий "some chars have been received"
приводят к ужасному коду по той причине, что вы открываете. Ваш основной поток должен быть свободен для обработки сообщения о том, что символы были получены, но в то же время у вас должен быть параллельный процесс, ожидающий, что эти принятые символы завершат четкую инструкцию. В управляемой событиями не существует разумного решения для управления интерфейсом и порта связи одновременно в одном потоке.
Набор компонентов, таких как AsyncPro **, например, переносит эту функциональность в пакеты данных, в которых используются синхронные события, но где компоненты управляют обнаружением начала и конца строки (или байтов) для рабочего потока. Это удаляет один уровень опроса из основного потока (т. Е. Вы всегда получаете событие, когда полный пакет данных прибыл, а не частичный). Кроме того, вы можете переместить работу связи в пользовательский поток и управлять этим самостоятельно.
В любом случае это лишь частично решение, конечно, поскольку вы по-прежнему не можете писать длинные процедурные методы в синхронных обработчиках событий, которые требуют ожидания com-трафика.Второй уровень опроса, который управляет последовательностью полных инструкций, по-прежнему будет нуждаться в том, чтобы перекачать очередь сообщений, если ваша одна процедура должна реагировать на последовательность более чем одной команды comport. То, о чем вам нужно подумать, - это разбить ваши длинные методы на более короткие куски, каждый в ответ на конкретные сообщения устройства.
В качестве альтернативы, для интенсивной процедурной автоматизации процесса также часто рекомендуется перемещать эту работу в фоновый поток. Таким образом, ваши рабочие потоки могут блокировать объекты синхронизации (или опросы в циклах занятости для обновлений состояния), пока они ждут событий с аппаратного обеспечения. Один поток может управлять трафиком с низким уровнем трафика, анализировать и ретранслировать эти команды или пакеты данных, тогда как второй поток может управлять процессом более высокого уровня, который обрабатывает последовательность полных команд comport, которые составляют ваш более крупный процесс. Основной поток должен в первую очередь отвечать только за сбор данных этих сообщений между рабочими, а не на то, чтобы самому ждать.
Смотрите также: I do not understand what Application.ProcessMessages in Delphi is doing
** VAComm
может также поддерживать что-то вроде этого, я не знаю. API и документация не доступны для TMS для ASync32, поэтому вам необходимо проконсультироваться с вашей местной документацией.
Что касается голосования, я допустил ошибку здесь, что могу исправить? –
+1 от меня ... это правильно, по существу, и ответы на уровне, соразмерном с вопросом. Похоже на голосование. –