Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.12.25;
Скачать: CL | DM;

Вниз

Почему событие WM_TIMER у окна со временем начинает тормозить, и   Найти похожие ветки 

 
VirEx ©   (2005-12-03 02:42) [0]

Почему событие WM_TIMER у окна со временем начинает тормозить: делаю окно createwindow(), создаю таймер SetTimer(), и т.п.
всё работает отлично (по времени), но если программа долго не используется (но находится в работе), это событие (WM_TIMER) начинает "опаздывать" когда я вновь начинаю использовать программу (вызываю её функции и т.п.).
У меня программа WinConsul , исходный код доступен на http://winconsul.kladovka.net/ ("старый" официальный сайт http://Virex-84.narod.ru/)
может перед каждым вызовом SetTimer нужно узнавать текущее время GetTickCount?


 
VirEx ©   (2005-12-03 02:47) [1]

прошу прощения http://winconsul.kladovka.net.ru/ :)


 
Ihor Osov'yak ©   (2005-12-03 02:48) [2]

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

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


 
VirEx ©   (2005-12-03 03:32) [3]

дело в том что моя программа по вызову горячей клавишы устанавливает новый таймер для выдвигания окна, а когда окно "выползет" окончательно таймер убивается, аналогично и с "задвиганием" окна.
может есть способ "растормошить" диспетчера сообщений windows для моей программы? всё работает на Win XP


 
Джо ©   (2005-12-03 06:17) [4]


>  [3] VirEx ©   (03.12.05 03:32)

А зачем тут таймер вообще? Запускаем отдельный поток, в котором и совершаются действия по "выдвиганию" окошка. Окошко выдвигается, поток умирает.


 
Джо ©   (2005-12-03 06:29) [5]


> [4] Джо ©   (03.12.05 06:17)

Сорри, я тут выпимши, вопрос, кажется не так понял.


 
Набережных С. ©   (2005-12-03 13:08) [6]


> Ihor Osov"yak ©   (03.12.05 02:48) [2]


> сори, тут уже не помню - либо приложения, либо окна

Извини за занудство, но ни у окон, ни у приложений очередей сообщений не бывает:)) Они бывают только у потоков.


 
VirEx ©   (2005-12-03 14:17) [7]

Набережных С.
тогда получается нужно делать поток (нить, thread) ?


 
Набережных С. ©   (2005-12-03 15:17) [8]


> VirEx ©   (03.12.05 14:17) [7]

Ничего не получается:) Все, что сказал Ihor Osov"yak в [2] справедливо, если я все правильно понял:) Единственная неточность мной указана, но в твоем случае она принципиального значения не имеет.


 
VirEx ©   (2005-12-03 15:37) [9]

блин, а кто знает как выгрузить приложение в файл подкачки и по мере надобности полностью загружать его в ОЗУ? как например делает плагин к Miranda IM, правда не помню как называется...


 
Карелин Артем ©   (2005-12-04 12:45) [10]

tweakmiranda имя его


 
Набережных С. ©   (2005-12-04 14:36) [11]


> VirEx ©   (03.12.05 15:37) [9]


> как выгрузить приложение в файл подкачки

Способ простой. Если запускать приложение со съемного носителя, то оно, AFAIK, прямиком попадет в файл подкачки, и никакой плагин не нужен. А если программа ничего не делает, то ее система сама выгрузит из ОЗУ, если ей понадобятся занятые программой страницы.

> и по мере надобности полностью загружать его в ОЗУ

И это, AFAIK, тоже не сложно - надо просто обратиться ко всем страницам памяти, занятым приложением, но нафига? Windows и без того с этим прекрасно справляется, тем более на современных машинах. А на слабых машинах это вообще вредительство, IMHO.

Ни то, ни другое нафиг не нужно. Тут была ветка, про самую бесполезную программу - вот этот плагин как раз оно самое, если он действительно это делает.


 
VirEx ©   (2005-12-04 16:12) [12]

да знаю я что Win выгружает и загружает обратно неиспользуемые сегменты памяти программы, просто гдето видел в Kernel API такую фичю... не могу вспомнить где...


 
Kerk ©   (2005-12-04 16:14) [13]

VirEx ©   (04.12.05 16:12) [12]

А зачем она тебе? :))


 
VirEx ©   (2005-12-04 17:26) [14]

ды чтоб диспетчер сообщений Win больше уделял внимания моей программе когда я её вызываю :)


 
Набережных С. ©   (2005-12-04 17:33) [15]


> VirEx ©   (04.12.05 17:26) [14]

Это решается установкой класса приоритета процесса.


 
VirEx ©   (2005-12-04 18:06) [16]


> Набережных С. ©   (04.12.05 17:33) [15]

если бы так, я б давно уже решиб бы эту проблему


 
Набережных С. ©   (2005-12-04 19:42) [17]


> VirEx ©   (04.12.05 18:06) [16]

Ладно.

Таймер работает через сообщения, как тебе, вероятно, известно. То есть система ставит его события в очередь сообщений. Следовательно, чтобы среагировать на приход сообщения от таймера, программа, точнее кодовый поток, должен обратиться к свой очереди. Вот, допустим, твое приложение ждет сообщения. Ты нажал в окне кнопку, в результате пришло сообщение. Главный поток его выбрал, обработал, в результате чего началось выполнения твоего кода, написанного в обработчике этой кнопки. Пока этот код выполняется, никакие другие сообщения, в том числе и от таймера, выбраны из очереди и обработаны быть не могут, если только твой код сам этого не делает. Если в это время придет сообщение от таймера, то оно так и будет лежать в очереди, пока не произойдет возврат из обработки предыдущего, в нашем случае из обработчика кнопки, грубо говоря. Если за это время потоку поступят другие сообщения, то сообщение от таймера еще отодвинется в очереди назад. Оно так и будет лежать в очереди, пока поток не обрабытает все остальные сообщения.

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

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


 
iZEN_   (2005-12-05 08:46) [18]

А зачем вообще использовать системную очередь сообщений?
А зачем вообще нужно использовать "ненадёжное" и "отодвигаемое" сообщение системного таймера?

Есть же TTimer.

> VirEx ©   (03.12.05 03:32) [3]
>
> дело в том что моя программа по вызову горячей клавишы устанавливает
> новый таймер для выдвигания окна, а когда окно "выползет"
> окончательно таймер убивается, аналогично и с "задвиганием"
> окна.
> может есть способ "растормошить" диспетчера сообщений windows
> для моей программы? всё работает на Win XP

Где-то: Timer.Enabled := True; //Включаем таймер

//Обработчик OnTimer
procedure TForm1.TimerTimer(Sender: TObject);
begin
  ///... код шага выдвигания окна
  если (окно выдвинулось полностью)
  то Timer.Enabled := False; //Выключаем таймер
end;

Никаких "лишних" тредов создавать не надо.


 
Lamer@fools.ua ©   (2005-12-05 08:50) [19]

>>iZEN_   (05.12.05 08:46) [18]

>А зачем вообще нужно использовать "ненадёжное" и "отодвигаемое" сообщение системного таймера?

Есть же TTimer.


Ой :-O


 
Набережных С. ©   (2005-12-05 11:13) [20]


> iZEN_

Ох, крут ты, брат, ох кру-у-ут!:)


 
begin...end ©   (2005-12-05 11:28) [21]

> iZEN_   (05.12.05 08:46) [18]

Совет такой: посмотреть реализацию TTimer. Оно рулёз.


 
WondeRu ©   (2005-12-05 11:37) [22]

mmtimer - вот решение всех проблем


 
Набережных С. ©   (2005-12-05 12:25) [23]


> WondeRu ©   (05.12.05 11:37) [22]

Неужели сразу всех? Да ты, брат, еще круче!


 
WondeRu ©   (2005-12-05 13:22) [24]

ДА! Это панацея!


 
Набережных С. ©   (2005-12-05 14:00) [25]


> WondeRu ©   (05.12.05 13:22) [24]

Ну и замечатьльно.


 
iZEN_   (2005-12-05 14:38) [26]


> begin...end ©   (05.12.05 11:28) [21]
> > iZEN_   (05.12.05 08:46) [18]
> Совет такой: посмотреть реализацию TTimer. Оно рулёз.

Посмотрел. Сделано х@#$%о. Не ожидал от Delphi такого позора.

Видимо придётся переделывать на Thread и считывать интервалы от системного времени.


 
VirEx ©   (2005-12-05 16:13) [27]


> iZEN_   (05.12.05 14:38) [26]
> Посмотрел. Сделано х@#$%о. Не ожидал от Delphi такого позора.

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


 
VirEx ©   (2005-12-05 16:14) [28]


> iZEN_   (05.12.05 14:38) [26]
> Посмотрел. Сделано х@#$%о. Не ожидал от Delphi такого позора.

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


 
VirEx ©   (2005-12-05 16:20) [29]

блин, сеть глючит :)


 
iZEN_   (2005-12-05 17:41) [30]


> VirEx ©   (05.12.05 16:13) [27]
> > iZEN_   (05.12.05 14:38) [26]
> > Посмотрел. Сделано х@#$%о. Не ожидал от Delphi такого
> позора.
>
> да почему позор, Дельфи же инкапсулировала всё из Windows
> архитектуры (т.е. скопировала), по другому с таймерами некак

Да потому, что WM_TIMER - ненадёжное событие, которое может ставиться в очередь, а может и не ставиться, может быть отодвинуто в любой момент времени, если есть более критический процесс или событие.
Таким образом эта техника не годится для time-critical приложений (да и любых других приложений мягкого реального времени), там нужно работать с собственными "таймерами" (с какими - я уже объяснял), не завязаными на Windows.


 
Игорь Шевченко ©   (2005-12-05 17:46) [31]

iZEN_   (05.12.05 17:41) [30]


> Таким образом эта техника не годится для time-critical приложений
> (да и любых других приложений мягкого реального времени)


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


 
iZEN_   (2005-12-05 18:00) [32]


> Игорь Шевченко ©   (05.12.05 17:46) [31]

Ядро WinNT гарантированно может отдавать приложениям "тики" с интервалом 10-25мс, но это совсем не значит, что с таким же интервалом будет посылаться системное сообщение WM_TIMER. ;))


 
VirEx ©   (2005-12-05 18:01) [33]


> iZEN_   (05.12.05 17:41) [30]

всёравно Delphi святое)


 
iZEN_   (2005-12-05 18:02) [34]


> VirEx ©   (05.12.05 18:01) [33]

Нее. В Java легче. ж)


 
Игорь Шевченко ©   (2005-12-05 18:14) [35]

iZEN_   (05.12.05 18:00) [32]


> Ядро WinNT гарантированно может отдавать приложениям "тики"
> с интервалом 10-25мс


Ты забыл одно условие - приложение должно быть способно их принять. Например, не быть вытеснено более высокоприоритетным приложением.


 
VirEx ©   (2005-12-05 19:01) [36]


> Игорь Шевченко ©   (05.12.05 18:14) [35]
>
> Ты забыл одно условие - приложение должно быть способно
> их принять. Например, не быть вытеснено более высокоприоритетным
> приложением.

а если приоритет моей программы наравне с обычными, т.е. при запуске было 5 программ - нормал (включая мою), прошло 15 мин, все остальные как обычно,  а моя с таймером замучена :)



Страницы: 1 вся ветка

Текущий архив: 2005.12.25;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.047 c
2-1133802239
loster
2005-12-05 20:03
2005.12.25
Повысить видимость метода


2-1134011223
HF-Trade
2005-12-08 06:07
2005.12.25
Сортировка по алфавиту Popupmenu


2-1134300848
злобная танька
2005-12-11 14:34
2005.12.25
ООП: виртуальные методы


14-1133611548
Alexis
2005-12-03 15:05
2005.12.25
Ахо, Хопкрофт, Ульман - "Структуры данных и алгоритмы"


2-1133885039
oleggar
2005-12-06 19:03
2005.12.25
быстрая запись