Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];

Вниз

Таймер не хочет работать...   Найти похожие ветки 

 
Chlavik ©   (2004-06-07 20:52) [0]

Вот код

procedure AddTimerUser;
begin
if not Assigned(GlobalTimerObj) then
 begin
  GlobalTimerObj:=TGlobalTimer.Create;
  GlobalTimerObj.Delay:=1000;
  GlobalTimerObj.Activate;
 end;
Inc(GlobalTimerUserCount);
end;

....

procedure TGlobalTimer.Activate;
begin
FID:=DefaultTimerID;
FID:=SetTimer(Handle,FID,FDelay,nil);
end;

...
TGlobalTimer=class(TMessageHandler)
TMessageHandler = обычный клас у которого есть WndProc и Handle

constructor TMessageHandler.Create;
begin
FHandle:=AllocateHWND(OnMessage);
inherited
end;


Так вот почемуто если первый раз вызвать  AddTimerUser с основного потока то всё пашет а вот если с другого то в wndproc не проходит wm_timer т.е. если создать экземпляр класса (GlobalTimerObj:=TGlobalTimer.Create) в другом потоке то не фига не работает, что делать ? Мне кажется что с процедурой AllocateHWND(OnMessage); что то не то творится если она не в основном потоке вызывается ... Помогите !


 
GuAV ©   (2004-06-07 21:12) [1]


>  если создать экземпляр класса (GlobalTimerObj:=TGlobalTimer.Create)
> в другом потоке

Код другого потока? может тупо Activate не вызывается?
и TGlobalTimer.Create на всяк случ


 
Chlavik ©   (2004-06-08 02:15) [2]

Дебаг показывает что всегда когда надо :)


 
Mim1 ©   (2004-06-08 02:42) [3]


> Мне кажется что с процедурой AllocateHWND(OnMessage); что
> то не то творится если она не в основном потоке вызывается
> ... Помогите !


А в  этом потоке есть цикл выборки вообщений?


 
Chlavik ©   (2004-06-08 02:49) [4]


procedure TMessageHandler.OnMessage(var Message: TMessage);
begin
Dispatch(Message);
end;

причём виртуальный
а у TGlobalTimer есть

procedure OnTimer(var Message:TWMTimer); message WM_TIMER;



 
Mim1 ©   (2004-06-08 03:15) [5]

Насколько велик код "неосновоного потока", может его сюда закинуть?


 
Digitman ©   (2004-06-08 09:17) [6]


> Chlavik ©   (08.06.04 02:49) [4]


и вот это ты называешь "циклом" ?


 
Chlavik ©   (2004-06-08 14:24) [7]

А за зачем мне цикл?????? С помощью AllocateHWND(OnMessage); я связываю процедуру обработки сообщений OnMessage с хэндлом ... всё должно работать без всяких циклов ... Может кто топредалгает сделать еще один цикл с GetMessage ? но это же помойму чють не то ..


 
Chlavik ©   (2004-06-08 14:29) [8]

Как же тогда создаются окна в других потоках?? цикл обработки сообщений у приложения вить то один!!??


 
Digitman ©   (2004-06-08 14:42) [9]


> Chlavik ©   (08.06.04 14:24) [7]



> А за зачем мне цикл??????


за надом !


> всё должно работать без всяких циклов


ничего подобного - цикл обязан в том или ином виде присутствовать


> Может кто топредалгает сделать еще один цикл с GetMessage


я предлагаю ...хоть с GetMessage, хоть с PeekMessage, но сообщения должны тем или иным образом выбираться из очереди и либо обрабатываться непосредственно либо диспетчеризоваться штатным для оконного механизма образом - по DispatchMessage()


> Как же тогда создаются окна в других потоках??


окна в любых потоках создаются одинаково - вызовом CreateWindow[Ex]


> цикл обработки сообщений у приложения вить то один!!??


по умолчанию - да, один ... его за тебя сделал и запустил Борланд в методе Application.Run .. и цикл там ответственен за ожидание/выборку/диспетчеризацию сообщений ОСНОВНОМУ потоку, который по умолчанию и безусловно создается при старте любого процесса

если же ты создал еще один или более доп.код.потоков, то ТЫ САМ (а не Борланд !) ответственен за создание очереди сообщений и за создание/работу цикла ожидания/выборки/обработки/диспетчеризации сообщений потоку и окнам, созданным в его контексте


 
Digitman ©   (2004-06-08 14:50) [10]


> Chlavik


осознай главное - поток А знать ничего не знает и не обязан знать ни о каких сообщениях какому-либо иному потоку В

каждый поток ответственен за самостоятельную организацию СОБСТВЕННОЙ очереди сообщений и алгоритма обработки этой очереди

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


 
Mim1 ©   (2004-06-08 15:47) [11]

Хочется добавить "Никакого VCL в неосновном потоке".
И еще, может в дополнительном потоке обойтись без таймера. Например sleep.


 
Digitman ©   (2004-06-08 15:58) [12]


> Mim1 ©   (08.06.04 15:47) [11]



> Никакого VCL в неосновном потоке


ты неправ

к примеру, никто и ничто не ограничивает тебя в создании невидимого по умолчанию объекта-наследника класса TForm и монопольного обращения к многим методам/св-вам этого VCL-объекта.. и никаких исключенийт при этом не получишь ... проблемы же начнутся как минимум с момента попытки выполнить метод Show[Modal]() этой формы


> может в дополнительном потоке обойтись без таймера


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


 
Chlavik ©   (2004-06-08 17:22) [13]

Просто таймер через PulseEvent сбрасиывет hEvent который юзают многие потоки вот в чём прикол ...


> Например sleep


Sleep а потом еще выполнение кода - вряме между итерациями цикла далеко будет не столько сколько надо ...


 
Chlavik ©   (2004-06-08 17:29) [14]


> если же ты создал еще один или более доп.код.потоков, то
> ТЫ САМ (а не Борланд !) ответственен за создание очереди
> сообщений и за создание/работу цикла ожидания/выборки/обработки/диспетчеризации
> сообщений потоку и окнам, созданным в его контексте


Thank"s ... не знал... Я думал что цикл один на весь процесс. Тогда всё понятно...


 
Digitman ©   (2004-06-08 17:31) [15]


> Просто таймер через PulseEvent сбрасиывет hEvent который
> юзают многие потоки вот в чём прикол ...


чавой-тооо ? это здесь при чем ? прежде чем что-то по какому-то поводу выполнило АПИ-вызов PulseEvent(), это "что-то" должно получить управление, будучи вызванным на исполнение тем или иным образом ... без цикла и без диспетчеризации никто и ничто не  передаст управление на фрагмент кода, выполняющий PulseEvent() !!


> Sleep а потом еще выполнение кода - вряме между итерациями
> цикла далеко будет не столько сколько надо ...


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


 
Chlavik ©   (2004-06-08 17:38) [16]

procedure TGlobalTimer.OnTimer(var Message: TWMTimer);
begin
PulseEvent(FhEvent);
end;

while not Terminated do
 begin
  WaitForMultipleObjects(Length(FWaitObjects),@FWaitObjects,false,INFINITE);
  Inc(FDelayCount);
  if FDelayCount>FTimeOut then Include(FStatus,tsTimeOut);
  if Assigned(FOnTimer) then DoOnTimer;
 end;
где FWaitObjects[0] это тот самы hEvent

Это заниматся дурью... ???


 
Digitman ©   (2004-06-08 17:44) [17]


> Chlavik ©   (08.06.04 17:38) [16]


> Это заниматся дурью... ???


а то нет !?

не дурь ли не анализировать в дан.случае рез-т выполнения WaitForMultipleObjects() !?

я ведь понятия не имею, какой трэд создает ивент-объект ... а ну как WaitForMultipleObjects() вернет WAIT_ABANDONED_+  ... ?!!


 
Chlavik ©   (2004-06-08 17:53) [18]

Не спеши тема другая была, дай код доописать ....


 
Chlavik ©   (2004-06-08 17:57) [19]

Ды и при чём тут WAIT_ABANDONED  к Event object ???? Это же не Mutex !!!


 
Mim1 ©   (2004-06-08 20:09) [20]


> > Например sleep


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

Если подход со слипом вас устраивает то


> Sleep а потом еще выполнение кода - вряме между итерациями
> цикла далеко будет не столько сколько надо ...


Вы же знаете сколько сколько надо? :)
тогда код с вот таким шаблоном вам поможет

// предположим что вам надо чтобы ваш код срабатывал каждую секунду
// тогда

procedure execute;
var dw:dword;
begin
 while true do
   begin
     if terminated then exit;  

     dw := gettickcount;
     // делаем некоторую задачу
     dw := 1000 - gettickcount - dw;

     if terminated then exit;  

     sleep(dw);
   end;
end;


Такой код будет срабатывать каждую секунду при условии что "некоторая задача" выполняется не более секунды. (что вполне эквивалентно таймеру).


 
Chlavik ©   (2004-06-09 01:27) [21]

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


 
Mim1 ©   (2004-06-09 03:56) [22]


> что со системой будет ... .

И что будет с системой? Зачем вам высокий приоритет? И каким боком вопрос о приоритетах относится к вопросу о таймерах?



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

Форум: "Основная";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.035 c
3-1085634334
radix
2004-05-27 09:05
2004.06.20
Поиск по полю BLOB


1-1086603969
Алексей
2004-06-07 14:26
2004.06.20
Как сохранить в файл TListItem


3-1085476371
VLAD-MAL
2004-05-25 13:12
2004.06.20
Синхронизация наборов данных.


14-1086167010
arbin
2004-06-02 13:03
2004.06.20
Как вам это


1-1086594204
Прямой
2004-06-07 11:43
2004.06.20
Вопрос про TThread





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский