Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Проблема с Application.ProcessMessages / 25 сообщений из 46, страница 1 из 2
22.04.2006, 11:57:37
    #33684174
Проблема с Application.ProcessMessages
Есть цикл, в котором рисуется некоторая кривая (график). Нужно, чтобы она выводилась не вся сразу, а по шагам, последовательно (э... Как будто мы ведем карандашом по бумаге, а за грифелем появляется след).

Сначала я сделал просто задержку при рисовании Sleep(SleepTime). Но оказалось, что если SleepTime = 1 и больше, то получается очень медленно.

Тут я заметил, что вместо Sleep() можно вставить Application.ProcessMessages, - он тоже дает задержку, но меньшую, чем Sleep(1):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 Repeat 
      If  (Form4.CheckBox3.Checked) then   begin  Application.ProcessMessages;sleep(SleepTime); end ;
      If  (i  mod   1000 )= 0   then  Application.ProcessMessages;
     x:=Round(Mas3[i, 1 ]-Mas3[i, 0 ]* 1 . 414214 / 4 );
     y:=Round(Mas3[i, 2 ]+Mas3[i, 0 ]* 1 . 414214 / 4 );
     Imag.Canvas.LineTo((O1.x-x), (O1.y-y));
     i:=i+ 1 ;
 Until  (i=MasLength)  or  Stop;

Все бы хорошо, но вот беда - когда строится график, программа очень медленно реагирует на другие события (нажатие на кнопку, котороая меняет значение переменной Stop, нажатие "на рисунок", когда должно запуститься копирование его в буфер). Казалось бы Application.ProcessMessages запускается в каждом цикле - все должно срабатывать мгновенно. Ан нет.
В чем может быть дело?
Как сделать построение с задержкой?

Заранее благодарю за помощь.
...
Рейтинг: 0 / 0
22.04.2006, 12:25:13
    #33684199
Luchkin Dmitry
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
Федор_ФедорКазалось бы Application.ProcessMessages запускается в каждом цикле - все должно срабатывать мгновенно. Ан нет.
В чем может быть дело?
Как сделать построение с задержкой?

Заранее благодарю за помощь.
Не совсем опонял, что Вам таки нужно, "мгновенно" или "с задержкой", хочу только сказать, что насчёт "запускается в каждом цикле" - это мираж. далеко не в каждом.
...
Рейтинг: 0 / 0
22.04.2006, 12:25:38
    #33684200
Anatoly Podgoretsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
Федор_Федор
Казалось бы Application.ProcessMessages запускается в каждом цикле - все должно срабатывать мгновенно. Ан нет.
В чем может быть дело?
Как сделать построение с задержкой?

Заранее благодарю за помощь.
Application.ProcessMessages запускается в каждом цикле только если Form4.CheckBox3.Checked, а так через каждые 1000 итераций.
Sleep основан на системном таймере, а это в лучшем случае, или 10 мсек, или 55 мсек. Для более частой обработки надо использовать мультимедия таймер, с ним можно достигнуть примерно 1 мсек. Ну и возможно для рисования линий использовать LineDDA
...
Рейтинг: 0 / 0
22.04.2006, 12:27:17
    #33684202
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
Федор_ФедорЕсть цикл, в котором рисуется некоторая кривая (график). Нужно, чтобы она выводилась не вся сразу, а по шагам, последовательно (э... Как будто мы ведем карандашом по бумаге, а за грифелем появляется след).



открой для себя TThread (Synchronize в т.ч.).

также изучи некий TApplication.OnIdle (в тему Synchronize)
...
Рейтинг: 0 / 0
22.04.2006, 13:21:36
    #33684252
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
Хм. Если коротко, то Вы делаете максимально неправильно. Скажем, стоит во время вывода взять другое окно и протащить его над Вашим - и график может и не выжить.

Позволю себе просто приложить максимально упрощенный пример относительно правильной реализации.
...
Рейтинг: 0 / 0
22.04.2006, 13:38:04
    #33684264
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
softwarerХм. Если коротко, то Вы делаете максимально неправильно. Скажем, стоит во время вывода взять другое окно и протащить его над Вашим - и график может и не выжить.

Позволю себе просто приложить максимально упрощенный пример относительно правильной реализации.

кхм. я бы сказал - максимально упрощенный пример как раз неправильной
организации.

а) таймеры (вместо тредов)
б) буферизация изображения - тоже, конечно, вариант, но решение с
.DoubleBuffered и грамотной отработкой именно WM_PAINT - будет
все-же более приближено к истине (хотя - тут и про DirectX уже можно
подумать)

но как максимально упрощенный - пожалуй да.
...
Рейтинг: 0 / 0
22.04.2006, 13:41:14
    #33684267
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
grexhideа) таймеры (вместо тредов)
А зачем там тред? Чтобы делать в нем Sleep?

grexhideб) буферизация изображения - тоже, конечно, вариант, но решение с .DoubleBuffered и грамотной отработкой именно WM_PAINT - будет
все-же более приближено к истине (хотя - тут и про DirectX уже можно
подумать)
Хм. Вы всегда охотитесь на воробьев с пушкой?

Имхо таки стоит соразмерять цели и средства. Впрочем, я с интересом увижу решение с тредами и WM_PAINT, вкупе с объяснением, чем именно оно лучше для решения данной конкретной задачи.
...
Рейтинг: 0 / 0
22.04.2006, 13:55:24
    #33684277
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
softwarer
Хм. Вы всегда охотитесь на воробьев с пушкой?

Имхо таки стоит соразмерять цели и средства. Впрочем, я с интересом увижу решение с тредами и WM_PAINT, вкупе с объяснением, чем именно оно лучше для решения данной конкретной задачи.

ну не с пушкой ;)) но даже помповое ружье всяко предпочтительнее рогатки..

задача была именно динамической отрисовки графика, да так, чтобы
не было дерганий экрана, интерактивность выдерживалась на уровне (в смысле
не создавала неудобств пользователю), а также - вопрос с массой графиков
одновременно - зачем гонять бестолку буферы изображений, если они
в текущий момент пользователю и не видны ? (насчет WM_PAINT я, конечно
загнул, использовался примерно такой же метод, только не в TImage, а
в память .BMP напрямую, с отдельной ее отрисовкой по BitBlt - уход
от VCL дал весьма заметное снижение нагрузки на CPU - порядка 30-40%).

Но до DirectX тогда руки так и не дошли (сработал именно прицип
целесообразности затрат).. да и в аспекте терминальных сессий - совсем
не хотелось сильно заморачиваться. Но терминальные сессии как раз уже
и поставили крест уже на механизме BitBlt, но это - совсем другая история.

А таймеры, по моему скромному мнению, использовать вообще не разумно,
разве именно как костыль, дополняющий OnIdle - в остальных случаях их
применение просто нецелесообразно - именно в аспекте интерактивности и
в виду наличия механизма потоков (тредов).
...
Рейтинг: 0 / 0
22.04.2006, 14:07:44
    #33684289
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
и все же - насчет WM_PAINT - от скорости
обновления графика зависит.

если график обновлять раз в минуту - то TImage и пр. как
раз и не нужны - как раз более чем достаточно именно WM_PAINT (.Invalidate),
и даже .DoubleBuffered уже как-бы и не сильно нужен.

но за треды - именно потому, что может быть еще и ожидающее событие какое,
а не только фиксированный квант времени обновления... а если скорость
обновления <5 сек, то альтернатив тредам просто нет.
...
Рейтинг: 0 / 0
22.04.2006, 14:11:58
    #33684293
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
grexhideну не с пушкой ;)) но даже помповое ружье всяко предпочтительнее рогатки..
Сомнительно, сомнительно.

grexhideзадача была именно динамической отрисовки графика, да так, чтобы не было дерганий экрана, интерактивность выдерживалась на уровне (в смысле не создавала неудобств пользователю), а также - вопрос с массой графиков одновременно
Где? 8-[ ] (как следует протерев глаза) Так где все-таки? Либо я тупой, либо в упор не вижу.

grexhideуход от VCL дал весьма заметное снижение нагрузки на CPU - порядка 30-40%)
Хм. Безусловно. Но в примере решения простой задачи стоит писать коротко-ясно-стандартно. Когда наш собеседник дойдет до "TImage не удовлетворяет" - он уже легко сможет его заменить.

grexhideА таймеры, по моему скромному мнению, использовать вообще не разумно, разве именно как костыль, дополняющий OnIdle - в остальных случаях их применение просто нецелесообразно - именно в аспекте интерактивности и
в виду наличия механизма потоков (тредов).
Хм. Скажем так, я сомневаюсь в существовании аргументации, показывающей преимущество OnIdle, тредов или чего-либо еще для решения данной конкретной задачи.

Критерий прост: ничего лишнего. В данном случае нечего параллелить - значит, треды не нужны. Здесь нет, например, распараллеливания вычислений и отрисовки - у автора темы координаты посчитаны заранее, у меня их расчет мягко говоря быстр. А раз так - делать отдельный поток - значит делать синхронизацию двух ничего не делающих потоков. Зачем? OnIdle в данном случае хуже тем, что потребует самостоятельно контролировать временные промежутки, обеспечивая плавность и равномерность отрисовки.
...
Рейтинг: 0 / 0
22.04.2006, 14:18:31
    #33684302
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
grexhideесли график обновлять раз в минуту - то TImage и пр. как
раз и не нужны - как раз более чем достаточно именно WM_PAINT (.Invalidate),
и даже .DoubleBuffered уже как-бы и не сильно нужен.
Не согласен.

1. Если обновлять раз в минуту, DoubleBuffered действительно не нужен. Но для двадцати раз в секунду без него некрасиво.

2. Image в данном случае - "решение в ноль строк", альтернативное TBitmap+WM_PAINT (решение существенно больше чем в ноль строк). Итого, до тех пор, пока оно не мешает, это наиболее удачное решение.

grexhideно за треды - именно потому, что может быть еще и ожидающее событие какое,
Какое? Не вижу в постановке задачи никакого ожидающего события.
...
Рейтинг: 0 / 0
22.04.2006, 14:20:51
    #33684305
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
softwarer
Где? 8-[ ] (как следует протерев глаза)


да ладно, все это - полет буйной постановочной фантазии.

у нас просто была цель - создать один раз некое универсальное решение,
удовлетворяющее нескольким режимам и всевозможным
аспектам эксплуатации (именно задача динамических графиков от показаний датчиков).

потому каждый раз делать временное решение - на практике, себе дороже, если
ты, конечно делаешь промышленную систему, а не курсовой какой (как
в случае "Федор Федор")

а с другой стороны - проблема графиков... сравнить, к примеру,
Quest Spotlight и Oracle 10G Enterprise Manager....

в первом модель тредов, во втором - модель таймеров (усугубленная во сто
крат кривой реализацией AJAX)... но тут боюсь оказаться голословным и
не совсем объективным.
...
Рейтинг: 0 / 0
22.04.2006, 14:23:58
    #33684307
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
softwarer
grexhideно за треды - именно потому, что может быть еще и ожидающее событие какое,
Какое? Не вижу в постановке задачи никакого ожидающего события.

изначальной - да, в целом - не совсем. элементарный вопрос - ожидание события
от устройства. в один момент может потребоваться опрос как раз 20 раз в секунду,
в остальных случах - устройство спит. (график не обязательно двигать
раз в секунду - достаточно сдвигать раз в минуту на минуту в целом, а потом
линию дорисовывать по необходимости)
...
Рейтинг: 0 / 0
22.04.2006, 14:31:03
    #33684312
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
softwarerВ данном случае нечего параллелить - значит, треды не нужны.

уже есть. основной поток обработки сообщений Windows и
собственно поток отрисовки графика.

иначе мы что получим ? конкуренцию пользователя и строптивой
программы, усиленно занятой в основном потоке динамической отрисовкой
графика (задержка > .05 сек дает ощутимую потерю интерактивности)
...
Рейтинг: 0 / 0
22.04.2006, 15:20:05
    #33684340
Проблема с Application.ProcessMessages
Упс. Не ожидал такой бурной дискуссии.

Спасибо за помощь.

Это не курсовой. Если человек не шарит в Делфи, то это не значит, что он студент. Верно?

Это прога для студентов - изучать поляризацию света.

Делфи я знаю плохо. Мне важно как можно проще решить поставленную задачу.

Например, если мне нужно, чтобы появлялась справка по нажатию на кнопку, я пишу:
Код: plaintext
1.
  ShellExecute(Application.Handle, 'open', 'lissajous3D.chm', PChar('newitem2.htm'),  Nil , SW_SHOWNORMAL);
Мне достаточно одной строки. И пусть это тысячу раз неправильно, и нужно подключить модуль из 500 строк кода... То что мне нужно работает. Зачем усложнять?

Боюсь, здесь тот же случай...
Мне нужно, чтобы суммы колебаний появлялся на экране не сразу весь, а "потихоньку", последовательно, пошагово...

См. рис.
...
Рейтинг: 0 / 0
22.04.2006, 15:25:04
    #33684347
Проблема с Application.ProcessMessages
У меня все рисуется прекрасно и все вроде работает. Наверное все коряво и плохо написано, но - главное - работает.

Вот что плохо - когда я хочу скопировать рисуночек в Ворд, то щелкаю по Image (запускается процедура сохранения в буфер). Так вот. В режиме "пошагового построения" получается так: я щелкаю по экрану, а график продолжает себе спокойненько строиться дальше еще секунды три-пять. В итоге я получаю в буфере не тот рисунок, который хотел :-(
...
Рейтинг: 0 / 0
22.04.2006, 15:26:16
    #33684349
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
сделай .AVI файл и показывай его всем желающим....

или Flash - векторная графика всяко предпочтительнее..
...
Рейтинг: 0 / 0
22.04.2006, 15:29:03
    #33684351
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
я же говорю - треды !!!

там есть такая фишка...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
  EnterCriticalSection(FLogSection);
   try 
...
   finally 
    LeaveCriticalSection(FLogSection);
   end ;


ну и само собой в конструкторе-деструкторе соотвественно.

InitializeCriticalSection(FLogSection);

DeleteCriticalSection(FLogSection);
...
Рейтинг: 0 / 0
22.04.2006, 15:34:35
    #33684357
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
Федор_Федор
Это не курсовой. Если человек не шарит в Делфи, то это не значит, что он студент. Верно?

редкий аспирант сильно отличается полезностью и
технической грамотностью - от студента и от преподавателя.

Федор_Федор
Боюсь, здесь тот же случай...
Мне нужно, чтобы суммы колебаний появлялся на экране не сразу весь, а "потихоньку", последовательно, пошагово...


а насчет флеша и .avi - это забавно !

даешь интерактивные "дохументы" !

в аспекте скорого появления электронной бумаги данная идея становится
все менее экзотичной в своей "кабы не идиотичности" (как тут говорят некоторые).
...
Рейтинг: 0 / 0
22.04.2006, 15:54:49
    #33684374
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
grexhideу нас просто была цель - создать один раз некое универсальное решение,
Это, конечно, особый вопрос.

grexhideуже есть. основной поток обработки сообщений Windows и
собственно поток отрисовки графика.
Ой. То есть два потока, занятых в лучшем случае на 0.1% каждый.

grexhideпрограммы, усиленно занятой в основном потоке динамической отрисовкой графика
Хм. Как же надо ухитриться написать программу, чтобы она "усиленно занималась динамической отрисовкой графика"? Под отрисовкой я в данном случае понимаю процесс модификации bitmap-а, то, что делается внутри таймера.

grexhide(задержка > .05 сек дает ощутимую потерю интерактивности)
Согласен. И в данной конкретной программе все задержки, которые только могут быть, сосредоточены в WM_PAINT, вынести который в отдельный поток не очень-то просто. А выносить в поток содержимое OnTimer - только ради студенческого выпендрежа.
...
Рейтинг: 0 / 0
22.04.2006, 16:00:09
    #33684379
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
softwarer

ну вот.... хотелось как лучше, а получилось - как всегда ;)))

в принципе согласен - если нужно просто очень быстро сделать, то -
таймеры в руки.

на практике, в более-менее серьезном приложении, подобные злоупотребления
нарастают как снежный ком. вроде бы и ничего страшного, но от массы
полу- решений со временем получается та самая свалка кривых поделок,
с неумолимо стремящимся к нулю запасом прочности.
...
Рейтинг: 0 / 0
22.04.2006, 16:01:36
    #33684382
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
Федор_ФедорТо что мне нужно работает. Зачем усложнять?
Правильный сам по себе подход. Но тот фрагмент кода, который Вы привели, мало того что сложен, но еще и работать (хорошо) не будет.

Федор_ФедорМне нужно, чтобы суммы колебаний появлялся на экране не сразу весь, а "потихоньку", последовательно, пошагово...
Я дал Вам шаблон, как это делать. Вам достаточно будет только изменить несколько строк.

Федор_ФедорВ режиме "пошагового построения" получается так: я щелкаю по экрану, а график продолжает себе спокойненько строиться дальше еще секунды три-пять.
Так, как Вы написали - безусловно. Уверен, что строится он до тех пор, пока не сработает if i mod 1000 .

Опять-таки, в моем примере сажаете еще кнопку, или OnClick, или что хотите.
...
Рейтинг: 0 / 0
22.04.2006, 16:06:10
    #33684386
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
softwarer И в данной конкретной программе все задержки, которые только могут быть, сосредоточены в WM_PAINT

это не совсем так. вернее - совсем не так. буфер прорисовки можно
формировать в треде - а потом очень быстро (за миллисекунды - одним оператором bitblt) отобразить его в WM_PAINT. поставив критическую сессию, естественно.
...
Рейтинг: 0 / 0
22.04.2006, 16:09:39
    #33684388
grexhide
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
и, кстати, совсем не понятна привязка к WM_PAINT - рисовать можно
и без него, в принудительном порядке...

правда, хоть убей, не помню, какие там возможны проблемы в случае
тредов.
...
Рейтинг: 0 / 0
22.04.2006, 16:19:01
    #33684399
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с Application.ProcessMessages
grexhideна практике, в более-менее серьезном приложении, подобные злоупотребления нарастают как снежный ком. вроде бы и ничего страшного, но от массы полу- решений со временем получается та самая свалка кривых поделок,
с неумолимо стремящимся к нулю запасом прочности.
Я полностью согласен с описанием эскалации кривых решений, но в ходе нашей дискуссии не увидел ни одного, кроме сугубо религиозных, аргумента, при чем тут таймеры. В целом, имхо:

1. Тот, кто криво применяет таймеры, в потоках тем более таких дел наделает....
2. Уместно примененные таймеры ничем плохим не характерны.

По поводу выбора, имхо, также все довольно просто:

1. Ресурсоемкие операции, долгие ожидания и прочие вещи, надолго захватывающие выполнение, желательно выносить в отдельные потоки.

2. Короткие операции, выполняемые время от времени, желательно инициировать таймерами.

3. Признаком неуместно примененного таймера являются ухудшение интерактивности программы, усложнение кода таймера, попытка разбить выполняемое на куски типа "это сейчас, это в следующем срабатывании" итп.

4. Признаком неуместно примененного потока является слишком частая его синхронизация с другими потоками; ситуация, при которой поток большей частью ожидает времени, когда ему будет пора работать.

5. И применение таймеров, и применение потоков, требует определенного уровня грамотности разработчика и соблюдения соответствующей "техники безопасности".
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Проблема с Application.ProcessMessages / 25 сообщений из 46, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]