| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Наставьте на путь истинный! |
| Автор: beard42 6.2.2010, 21:03 |
| Суть проблемы: Есть устройство, с которого нужно переодически получать данные. Связь осществляется через Bluetooth. Для получения ответа от устройства ему нужно сначала послать запрос. Данные необходимо получать ежесекундно и соотносить их со временем. При работе, когда устройство находится на пределе устройчивого соединения (т.е. расстояние между устройством и компьютером большое), наблюдаются нарушенияя связи (либо не доходит запрос, либо "мусор" приходит в ответе). Поэтому принимаемые данные приходится дополнительно обрабатывать. Сейчас все организовано так: В отдельном процессе устанавливается таймер (через CreateWaitableTimer) и через WaitForMultipleObjects в методе Execute оживается. После этого устанавливается флаг, отправляется запрос на одну порцию данных и ждем, пока флаг не сбросится. При получении ответа, производится попытка его разбора (т.е. определяется что за данные пришли) и сбрасывается флаг. Далее увеличиваем счетчик запросов, выставляем флаг и отправляем запрос на вторую порцию. По тому же алгоритму ждем сброса флага. При разборе второй порции данных результаты первого и второго разбора отправляются в основной поток программы (через Synchronize), время отправки запоминается, счетчик запросов уменьшается. Если после разбора второй порции данных устанавливается, что счетчик запросов больше одного, то данные делятся на несколько порций, в соответствии со счетчиком запросов и каждая порция отправляется в основной поток. После отправки возвращаемся в Execute. Вот мы и добрались до сути вопроса. Проблема в том, что весь процесс отправки запросов, ожидания ответа и его разборки, ну и отправки полученного результата в основной поток, длится иногда больше, чем секунду. При этом, естественно, программа никак не отлавливает данный факт. :( Связь через ком-порт ведется при помощи модуля SerialNG (http://www.domis.de/serialng.htm). Подскажите идею как все это лучше организовать. Я пока вижу только один выход. Разделить отправку/прием данных и их разбор/отправку в основной поток по разным потокам. Вот только как соотносить данные со временем и отслеживать "провалы" в принятых данных? |
| Автор: kami 6.2.2010, 21:44 |
А зачем ожидать ответ, если когда что-нибудь придет из порта, то возникнет событие OnRXчего_то_там? Отправлять запросы ежесекундно, а принимать - когда получится. |
| Автор: beard42 6.2.2010, 23:45 |
А как определить к какому запросу относится ответ? А если он (ответ) только через секунду придет? |
| Автор: kami 7.2.2010, 00:55 |
Вот этого я не знаю, зато можете знать Вы. У Вас же в руках протокол обмена компьютер <=> устройство. Ну опять-таки, вопрос не по адресу - я же не знаю, сколько времени это устройство обрабатывает запрос. Есть ли разница, какой ответ какому запросу соответствует? Если да - в качестве примера могу предложить следующее: заводим буфер запросов FIFO (к примеру - в TStringList). Отправляя очередной запрос в порт, помимо этого добавляем в stringList последним элементом. Получив ответ - забираем первый запрос из списка в StringList и удаляем его оттуда. Полученный ответ и "выдернутый" запрос отдаем основному потоку. Добавлено @ 01:00 Ну и в дополнение - Syncronize "отдает управление" основному потоку и ожидает окончания его работы в этой процедуре. Ибо основывается на SendMessage. Если тип данных позволяет, я бы лучше воспользовался PostMessage, что позволит добиться бОльшей асинхронности. (то есть - отдали данные в основной поток, а когда он их получит и что будет с ними делать - уже не проблема потока, занимающегося транспортной частью. Его это не колышет и не приостанавливает работу на время, пока основной поток обработает данные). |