![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Доброе утро!
У меня возник вопрос. Пару месяцев назад начал работать с делфи. Подскажите как реализовать следующую задачу. Вот как сейчас работает моя программа: - слушает определенный порт - если на этот порт приходит запрос от клиента, то обрабатывает этот запрос - если в момент обработки запроса от клиента приходит еще один запрос, то его необходимо отклонить Запрос представляет из себя строку с параметрами. Получив эти параметры программа вызывает функцию из Dll, которая отправляет эти параметры на устройство через COM- порт. Устройство обрабатывает данные и возвращает ответ. Суть проблемы. Обработка данных устройством занимает 15-20 секунд, и в это время все запросы приходящие на порт, который слушается -- становятся в очередь и не обрабатываются пока не отработает функция. Это не допустимо. Необходимо, чтобы в случае занятости -- клиент сразу получал ответ. Как наладить параллельную работу прослушки порта и остальной работы программы? Вот участок кода, который обрабатывает запросы: Код:
if ServerSocket.Socket.ActiveConnections = 1 then begin //тут читаем параметры запроса CheckRequest; // обрабатывает запрос (15-20 секунд); GetParam:=''; exit; end else begin ServerSocket.Socket.Connections[ServerSocket.Socket.ActiveConnections-1].SendText('Сервер не доступен'); Application.ProcessMessages; Buffer.Lines.Insert(0,'Отключаем лишний коннект'); Application.ProcessMessages; ServerSocket.Socket.Connections[ServerSocket.Socket.ActiveConnections-1].Close; Application.ProcessMessages; ConNum; end; |
#2
|
||||
|
||||
![]() завести флаг занятости устройства. устанавливать его при получении запроса от клиента и сбрасывать после получения ответа от устройства. в обработчике запросов от клиентов проверять флаг занятости и отвергать запросы (сообщать клиенту о занятости) при его активности.
Пишу программы за еду. __________________ |
#3
|
||||
|
||||
![]() ...ну и конечно CheckRequest обрабатывать в отдельном потоке.
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#4
|
|||
|
|||
![]() Цитата:
Это у меня все реализовано. Флагом является проверка на уже существующий коннект. Если он есть, то все остальные запросы получают ответ о занятости устройства. НО, ответ о занятости не посылается, пока не отработает функция с COM портом. Т.о. все клиенты которые соединяются в момент работы программы с ком портом -- ожидают окончания этой работы и только потом получают ответы. Цитата:
Я только начал читать про потоки. Подскажите пожалуйста основные моменты, как в моем случае это реализовать Последний раз редактировалось M.A.D.M.A.N., 21.10.2013 в 15:15. |
#5
|
||||
|
||||
![]() Предроложим что:
BusyFlag - глобальная переменная в рамках данного модуля TCheckRequestThread - поток который обрабатывает запрос на внешнем устройстве, после обработки данных он самоуничтожается. Код:
if ServerSocket.Socket.ActiveConnections = 1 then begin //тут читаем параметры запроса if not BusyFlag then begin BusyFlag:=True; TCheckRequestThread.Create; //запускаем поток (возможно, и даже скорее всего, // в конструктор нужно быдет передать некоторые параметры) // CheckRequest; // обрабатывает запрос (15-20 секунд); end else begin //тут отклоняем запросы пользователей end; GetParam:=''; exit; end else begin ServerSocket.Socket.Connections[ServerSocket.Socket.ActiveConnections-1].SendText('Сервер не доступен'); Application.ProcessMessages; Buffer.Lines.Insert(0,'Отключаем лишний коннект'); Application.ProcessMessages; ServerSocket.Socket.Connections[ServerSocket.Socket.ActiveConnections-1].Close; Application.ProcessMessages; ConNum; end; Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#6
|
|||
|
|||
![]() Цитата:
Понял. Спасибо попробую. Сейчас читаю про потоки. Возник вопрос: Вот стандартный пример для обращения из потока к свойствам vcl компонент Код:
procedure MyThread.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; procedure MyThread.Execute; begin Synchronize(UpdateCaption); end; возможно ли через процедуру Synchronize обращаться напрямую к процедурам объекта TForm например есть вот такое Код:
procedure TForm1.UpdateCaption; begin Caption := 'Updated in a thread'; end; как можно вызвать эту процедуру в потоке? Это будет верно? Код:
procedure MyThread.Execute; begin Synchronize(TForm1.UpdateCaption); end; Последний раз редактировалось M.A.D.M.A.N., 22.10.2013 в 09:48. |
#7
|
||||
|
||||
![]() Цитата:
Пишу программы за еду. __________________ |
#8
|
|||
|
|||
![]() подскажите можно ли из потока вызвать функцию(из длл).
Функция описана так в TForm: и как это правильно сделать. Код:
private SetComParams : function(Num: Byte; Rate: DWord): Byte; stdcall; Последний раз редактировалось M.A.D.M.A.N., 22.10.2013 в 09:48. |
#9
|
|||
|
|||
![]() Так вызывать нельзя - метод должен быть описан внутри класса потока. Вызывай свой CheckRequest в MyThread.Execute; В твоем случае отсутствие синхронизации не приведет к сбою. Естественно CheckRequest должен быть описан в классе TMyThread.
Установи свойство MyThread.FreeOnTerminate в true. Флаг использовать не обязательно, достаточно проверить является ли MyThread nil. Если поток выполняется, то отвечай клиенту, что "занято", если поток nil, то создавай поток и запускай его (Resume). Рекомендую почитать про потоки и методы синхронизации подробнее. Последний раз редактировалось Sibay, 21.10.2013 в 16:26. |
#10
|
|||
|
|||
![]() спасибо, буду читать
|
#11
|
|||
|
|||
![]() Перечитал свое сообщение, немного неправильно сформулировано. "Так вызывать нельзя" относилось к предыдущему сообщению, а вызывать функцию из dll разумеется можно
![]() |
#12
|
|||
|
|||
![]() >Так вызывать нельзя - метод должен быть описан внутри класса потока.
Ну не совсем так. В Synchronize можно подать метод любого объекта, но обязательно метод и обязательно без параметров. |
#13
|
||||
|
||||
![]() Smallboy, или пользуйся тегами, или в бан, третьего не надо.
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |