|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
26.10.2011, 18:36 | #1 |
Пользователь
Регистрация: 14.10.2011
Сообщений: 20
|
Таймеры и модальные окна
Всем привет! Ребят подскажите пожалуйста!
Суть проблемы в следующем. Есть у меня таймер на главной форме, назначение его - периодический опрос регистров контроллера и отображение данных. Смысл в том что когда я вызываю модальное окно (ShowModal) таймер свое выполнение иногда (не всегда но иногда) прерывает! Подскажите пожалуйста как решить эту проблему? (Вместо таймера использовал поток, но потом от него отказался, так как иногда по непонятным причинам выполнение потока прерывается) Заранее спасибо! |
26.10.2011, 19:05 | #2 |
Участник клуба
Регистрация: 09.11.2007
Сообщений: 1,761
|
Модальное окно всегда прерывает основной поток. Зачем Вам модальное окно? Отсюда копать надо.
|
26.10.2011, 19:10 | #3 | ||
Старожил
Регистрация: 20.04.2008
Сообщений: 5,526
|
Цитата:
Цитата:
программа — запись алгоритма на языке понятном транслятору
|
||
02.12.2011, 15:09 | #4 |
Пользователь
Регистрация: 14.10.2011
Сообщений: 20
|
В общем с кодом разобрался, действительно внутри кода были ошибки и поэтому и таймер и поток свое выполнение прекращал. В итоге остановился на потоке.
По поводу окон - у меня в приложении есть так сказать каскадный вызов окон. На экране могут быть одновременно показано до 3-х форм, то есть главная форма программы вызывает вторую форму, а вторая форма вызывает третью, причем необходимо чтобы при вызове очередного окна предыдущие были недоступны, как это реализовать не используя модальные окна я не знаю, может кто подскажет? И более того появилась опять проблема... Поток считывания регистров ПЛК должен выполняться постоянно и осуществлять опрос регистров с заданной периодичностью(задержку между вып-ем считывания внутри потока реализовал посредством sleep), но при вызове модального окна во время выполнения процедуры считывания внутри потока поток свое выполнение приостанавливает ((. И возобновляет свое выполнение только после закрытия модального окна. Может кто подскажет в чем проблема? |
02.12.2011, 15:19 | #5 | |
Старожил
Регистрация: 20.04.2008
Сообщений: 5,526
|
Цитата:
выполнение процедуры остановлено и ждет ответа пользователя. вывод НЕ ИСПОЛЬЗОВАТЬ внутри потока ShowModal.
программа — запись алгоритма на языке понятном транслятору
|
|
02.12.2011, 16:44 | #6 |
Пользователь
Регистрация: 14.10.2011
Сообщений: 20
|
Так все бы нормально, и я понимаю что внутри потока ShowModal выполнение потока до закрытия модального окна прерывает. Модальное окно вызывается НЕ ВНУТРИ ПОТОКА. Поток опроса у меня никаких модальных окон не вызывает. А просто при вызове модального окна из любой формы поток свое выполнение приостанавливает, причем что самое интересное если модальное окно вызвано не во время выполнения процедуры опроса потока, а во время ожидания (sleep - реализованного внутри потока), то все нормуль, поток свое выполнение не приостанавливает, и поток выполняется дальше и выполняет периодический опрос с заданной частотой, а если мы модальное окно вызовем во время процедуры опроса, то выполнение приостанавливается.
Я может до этого проблему не полностью описал, но есть еще вот что... Та самая процедура опроса, во время которой из-за модальных окон поток свое выполнение и приостанавливает, включает процедуру ожидания квитанции реализованную в while true do ...Квитанция - от сервера опроса, реализованного на основе DDE технологии, то есть общая схема такая Прога посылает запрос через ClientConv (все это в потоке) на считывание регистров DDE серверу и ждет квитанции от сервера. Сервер считав регистры посылает проге (клиенту) квитанцию о необходимости обновления данных с сервера (то есть на стороне сервера так же присутствует компонент DDE клиента а на стороне клиента для получения квитанции присутствует компонент DDE сервера). Серверный DDE компонент на стороне клиента получив команду (квитанцию) на обновление данных присваивает значение заданной переменной (kvit) значение true. Значение данной переменной в цикле потока while постоянно и проверяется( while not(kvit) do Application.ProcessMessegs ). После данного цикла идет запрос к серверу со стороны клиента на обновление данных - ClientConv.RequestData. И дальше sleep до следующего этапа опроса. И вот я понимаю, что когда мы из программы и вызываем любое модальное окно во время цикла ожидания квитанции потока while , переменная квитанции почему-то не обновляется, хотя квитанция приходит и компонент DDEсервера на стороне клиент присвоение переменной производит, то есть отрабатывает и мы виснем... Передачу команд и квитанции реализовал через макросы... И вот еще... Без квитирования можно было бы обойтись если поставить в процедуре ClientConv.ExecuteMacroLines(...,fa lse) вместо false поставить true. То есть включить ожидание завершения макросов на стороне сервера и проверять постоянно завершение процедурой ClientConv.WaitStat, но опять же проблема (может я что не так делаю), даже когда на стороне сервера процедура ServerConv.OnExecuteMacro свое отработала, ClientConv.WaitStat все равно равен true и дальнейший доступ к серверу невозможен... (( в общем засада какая-то Если по моей схеме "клиент-сервер" я что-то непонятно объяснил, готов все пояснить в картинках |
02.12.2011, 18:31 | #7 | ||
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
Цитата:
Цитата:
"ковыряю изнутри" (с)
|
||
05.12.2011, 09:56 | #8 | |||||
Старожил
Регистрация: 20.04.2008
Сообщений: 5,526
|
Цитата:
Цитата:
А вы в курсе того что ShowModal тоже работает в ЭТОМ цикле. И МОДИФИЦИРЕТ параметры управления ДАННЫМ циклом, так как считает нужным. Вот вам и Цитата:
Цитата:
и пока все операции основного потока не будут выполнены дальше вы не продвинетесь. P.S. для синхронизации потоков используются семафоры и функции работы с ними Например Цитата:
программа — запись алгоритма на языке понятном транслятору
Последний раз редактировалось evg_m; 05.12.2011 в 10:58. |
|||||
05.12.2011, 15:30 | #9 |
Пользователь
Регистрация: 14.10.2011
Сообщений: 20
|
Ура!!!
В общем выявил я в чем проблема, результаты своих проб и ошибок выкладываю в примерах, надеюсь этот опыт поможет другим, если кто столкнется с такой проблемой или решит реализовывать какую либо задачу таким способом. Решение состоит в том что процедуру ожидания while необходимо реализовывать не в теле какой либо процедуры (пусть даже она является методом потока) (пример_1) а в теле самого потока (пример_2) - Execute. Для того чтобы меня правильно поняли сделал пару примеров. Код простой в принципе и без комментариев все понятно, но тем не менее прокомментирую. Пояснения привожу ниже... По поводу "это неправда" - пример_1. Полностью отражает тот механизм который был описан ранее. Попробуйте сами и убедитесь, выкладываю вместе с исходниками. Суть в следующем. Есть поток - TPotok, который мы запускаем нажатием кнопки "Запуск потока". Порядок действий в потоке следующий: 1 - вывод в поле memo момента начала выполнения потока 2 - ожидание прихода квитанции (ожидание когда переменная ExecuteCmd станет равной true - УЗКИЙ МОМЕНТ МОЕЙ ПРОГИ) 3 - вывод момента завершения потока 4 - разрушение потока по завершению выполнения Приход квитанции, а именно присвоение переменной ExecuteCmd:=true, симитировал двумя способами - посредством таймера - через пять секунд после запуска потока и из модальной формы посредством нажатия кнопки. Модальная форма вызывается нажатием кнопки "Модальное окно". Ну так вот, если запустить поток и не позднее 5-ти секунд с момента запуска вывести модальное окно, то в первом примере вы завершения потока (подтверждение тому вывод в поле memo - "end_дата/время") не дождетесь, не смотря на то что таймер свою задачу выполнит - присвоит переменной ExecuteCmd:=true - о чем будет свидетельствовать вывод даты/времени в memo поле "Результат работы таймера". Так же как я и говорил ранее ExecuteCmd:=true можно выполнить из модальной формы, но результата (завершения выполнения потока) не последует. Хотя все сделано вроде правильно и вызов процедуры в теле потока так же производится через Synchronize. пример_2 - такими недостатками не обладает, только потому что процедуру while занес непосредственно в тело потока а не косвенно через пусть даже процедуры потока. Большое всем спасибо за дискуссию и внимание к моей проблеме, надеюсь этот опыт будет еще кому-то полезен! |
05.12.2011, 17:24 | #10 | |
Старожил
Регистрация: 20.04.2008
Сообщений: 5,526
|
Цитата:
неверно Код:
более правильно основная работа потока ВНЕ процедуры synchonize. Код:
программа — запись алгоритма на языке понятном транслятору
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Закрыть все дочерние (модальные и.д.) окна программы | designer999 | Общие вопросы Delphi | 15 | 24.09.2011 18:49 |
Таймеры | tools | Qt и кроссплатформенное программирование С/С++ | 3 | 30.05.2010 23:12 |
Таймеры | Sergeu | Общие вопросы C/C++ | 2 | 25.03.2010 12:13 |
Таймеры | EdNovice | Общие вопросы .NET | 1 | 06.03.2009 11:26 |
Модальные окна | spamer | Общие вопросы Delphi | 4 | 01.03.2009 15:16 |