Форум: "Основная";
Текущий архив: 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.51 MB
Время: 0.033 c