![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Есть некий код, при выполнении которого программа зависает часа на два, пока не выполнится цикл. Знаю что можно этот цикл запихнуть в отдельный поток, а как это сделать не знаю, с потоками никогда не работал. Подскажите пожалуйста как это лучше сделать. Заранее спасибо.
Код:
|
#2
|
||||
|
||||
![]() Может просто по таймеру (компонент TTimer)? В свойстве Interval выставить нужный интервал (в мс) между срабатываниями таймера.
Чтоб сделать такое, нужно отказаться от конструкций "for" или "while" и прописать всё руками. Т.е. начальное состояние (i := 1) задаётся в основной программе, а инкремент переменной и опосля проверка на достижение предела, а также основные действия (преобразование посылки в СОМ порт и т.п.), прописывается в обработчике OnTimer. Таймер сразу не запускаете, сначала инициализируете переменные. Если надо - остановить таймер можно как из основной программы, так и в самом обработчике, при выполнении каких-либо условий. Последний раз редактировалось Guaho, 21.04.2020 в 15:09. |
#3
|
|||
|
|||
![]() А как я смогу выставить интервал, если я не знаю когда придет ответ из СОМ порта, он может придти через секунду, а может через пять.
|
#4
|
||||
|
||||
![]() Поставить малый интервал - скажем, 50 мс, тут зависит от самой задачи, насколько критичен интервал между наступлением события и началом его обработки. Ответ из порта как-то ведь проявляет себя, т.е. программно же можно определить, что он пришёл? Если да, то ставите проверку - есть ответ? Если нет, выход (т.е. "холостой ход" кода обработки приёма ответа порта).
|
#5
|
||||
|
||||
![]() Простой вариант: в цикл вставить вызов Application.ProcessMessages, тогда программа хоть со скрипом (в зависимости от длительности итерации цикла) будет реагировать на действия пользователя.
Сложный вариант: действительно оформить цикл как отдельный поток и сделать ассинхронный вызов, т.е. программа запускает поток, потом по таймеру проверяет, закончился ли поток. Простой вариант реализации: Поток, в отдельном модуле: Код:
А теперь вызов: Код:
Это грубый пример, просто что бы показать как это все работает. |
#6
|
|||
|
|||
![]() Сделал через таймер, вполне устраивает, даже можно остановить выполнение. Прогу пишу для себя, поэтому наверное так и оставлю, хотя понимаю что это не правильно. Просто учиться на 5ом десятке уже в лом, хоть и карантин. Спасибо огромное, что помогаете.
|
#7
|
|||
|
|||
![]() Таймер хорошо, если обработка укладывается в интервал срабатывания таймера. Если нет, то могут полезть глюки, которые будет тяжело ловить, бо как они будут лезть на первый взгляд в случайный момент.
Тоже самое с Application.ProcessMessages в теле цикла. Там интервал (время выполнения одной итерации цикла) определяется человеком, т.е. для человека должно казаться, что программа работает без зависаний. Это где-то 30-50 мс на выполнение одной итерации цикла. Во всех остальных случаях - отдельный поток или процесс. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Guaho (22.04.2020)
|
#8
|
|||
|
|||
![]() Я просто в обработчике событий таймера сперва его отключаю, выполняю преобразования, посылаю в СОМ порт, получаю ответ, его преобразовываю и включаю обратно таймер. Приложение хоть как то реагирует. И даже можно остановить запросы.
|
Этот пользователь сказал Спасибо rodionov_uv за это полезное сообщение: | ||
Guaho (22.04.2020)
|
#9
|
|||
|
|||
![]() Угу. Особенно надо обратить внимание на слова "хоть как то реагирует".
Опять же, если прога пишется для себя, то и так сойдет. Но если придется передавать кому-то еще, то придется менять. ЗЫ. А вообще, лучше привыкать сразу делать правильно. Лучше набить шишек на простых примерах, а в дальнейшем уже будешь знать как делать правильно... Но это мое мнение, для себя решай сам. |