Текущий архив: 2003.03.31;
Скачать: CL | DM;
ВнизНесколько таймеров не могут работать параллельно? Найти похожие ветки
← →
AlexVit (2003-03-19 12:39) [0]Я всех приветствую!
У меня вот что: в приложении используется несколько таймеров.
Если один из них работает достаточно долго (несколько секунд, к примеру), то остальные не выполняются (даже если подошло время для их выполнения, это проверено), пока первый таймер не закончит свою работу.
Можно ли как-то обойти это, т.е. сделать так, чтобы таймеры работали паралелльно, или же только потоки позволяют так работать?
Всем спасибо за внимание.
← →
Style (2003-03-19 12:42) [1]Лучше смотри TThread!
Но все зависит от задачи! Ты Что пытаешься сделать??
← →
Shirson (2003-03-19 12:42) [2]Если таймеры друг друга глушат (честно говоря не сталкивался), то thread - верный путь.
← →
han_malign (2003-03-19 13:02) [3]> Если таймеры друг друга глушат (честно говоря не сталкивался)
- событие таймера(ов), поступает через очередь сообщений в основном потоке приложения, поэтому о параллельном выполнении без Thread-ов не может быть и речи. При этом, если на долго блокировать основной поток обработкой события таймера(или любого другого), накопятся события таймера, котрые потом будут приходить сразу друг за другом, по мере обработки их и других сообщений, а не через указанный интервал... Система просто, с заданным интервалом, помещает сообщения таймера в очередь, а грамотное разгребание очереди (без загрузки основного потока до прихода следущего сообщения) - проблема программиста...
The WM_TIMER message is posted to the installing thread"s message queue or sent to the appropriate TimerProc callback function after each interval specified in the SetTimer function used to install a timer.
.....................
.....................
Remarks
The DispatchMessage function forwards this message when no other messages are in the thread"s message queue.
- вот как раз из-за Remarks, при грамотной(короткой) обработке события таймера, таймер обычно считается достаточно точным (+- 40..60 мс)...
Можно попробовать "TimerProc callback function", но поток все равно один, так что вероятнее всего - облом без Thread-ов...
← →
AlexVit (2003-03-19 13:09) [4]
> To Style (19.03.03 12:42)
Все дело в том, что мне требуется паралелльно работать с разными таблицами БД, через определенные промежутки времени. Я счел, что для этого больше всего подойдет TTimer, но не учел, что OnTimer может долго обрабатываться, и тогда остальные обработчики простаивают, что недопустимо. Теперь что же, мне весь код затачивать под потоки?! А там тысячи строк, которые опять придется тестировать...
← →
Style (2003-03-19 13:25) [5]> AlexVit
Да и тестировать придется обязательно..
Во первых с потоками не так просто работать! Тебе нужно синхронизировать сам процесс. Правильно расставить приоритеты. Лучше под поток выделить отдельный Unit что бы самому было удом.
Не в коем случае не рисуй (не поднимай Canvas)из потока на другой форме.. Иначе будут глюки.
Если надо выполнить какие нибудь изменения на другой форме используй для этого сообщения.
в константах пропиши свое сообщение например:
const
WM_THREAD_ACTION = WM_USER + 1;
TA_REPAINTFORM = 1;
TA_SETCAPTION = 2;
Далее в самой форме сделай процедуру обработки твоего сообщения
type
TForm1 = class(TForm)
...
public
procedure OnThreadAction(var Msg: TMessage); message WM_THREAD_ACTION;
А по получении сообщения
procedure OnThreadAction(var Msg....);
begin
case Msg.WParam of
TA_REPAINTFORM: Form.Repaint;
TA_SETCAPTION: Form.Caption := StrPas(pchar(Msg.Lparam));
end;
end;
Из Нити посылай сообщение следующим образом:
procedure TMyThread.Execute
begin
while not Terminated do
begin
....
....
PostMessage(WM_THREAD_ACTION, TA_SETCAPTION, "Title",0);
end;
end;
Да работы у тебя навалом!
← →
han_malign (2003-03-19 13:33) [6]> Не в коем случае не рисуй (не поднимай Canvas)из потока на другой форме.. Иначе будут глюки.
- не вводите в заблуждение, при этом просто используется TCanvas.Lock/Unlock
← →
Style (2003-03-19 13:35) [7]
- не вводите в заблуждение, при этом просто используется TCanvas.Lock/Unlock
Ввместо того чтобы переключать Lock Unlock куда лучше написать обработчик сообщений
← →
Anatoly Podgoretsky (2003-03-19 13:44) [8]AlexVit © (19.03.03 12:39)
Не выполняются возможно потому что ты не обрабатываешь сообщения, а одного таймера, что не достаточно, достаточно иметь список на один таймер, но это все равно не избавит от обработки сообщений. Еще одной причиной может быть то что у таймера низкий приоритет, ряд сообщений может быть пропущен.
← →
Style (2003-03-19 13:48) [9]Anatoly Podgoretsky © >>
Ты думаешь втавить обработку сообщений из таймера.?? Просто если у него там есть цикл ему внутри цикла придется обрабатывать сообщения других таймеров я так понимаю?
Помоему для такой задачи лучше TThread не найти!
← →
AlexVit (2003-03-19 14:13) [10]
> Anatoly Podgoretsky ©
Дело в том, что разные куски кода должны срабатывать через разные промежутки времени, поэтому применяю несколько таймеров. А сообщения в таймерах я действительно не использую, не было пока такой необходимости.
> Style
Действительно в таймерах я использую циклы. Похоже, придется все под потоки переделывать, мда... :(
← →
y-soft (2003-03-19 14:26) [11]Тут явно задача мнопоточная. Можно использовать один таймер и по его тикам запускать потоки или выбирать их из пула. Но, как уже писал han_malign © (19.03.03 13:02), сообщение WM_TIMER имеет очень низкий приритет, поэтому отдельные сообщения могут теряться, поэтому в качестве таймера лучше использовать что-нибудь более надежное...
← →
alxx (2003-03-19 14:34) [12]Взять таймер и в OnTimer запускать нить. Правда если много нитей будет, то виндовс раскорячится.
А лучше в онтаймер ставить suspend/resume одной нити. Сообщения же можно использовать WM_User
← →
MBo (2003-03-19 14:54) [13]в RXLib есть TimerList
← →
AlexVit (2003-03-19 15:34) [14]
> alxx ©
Похоже, оптимальное решение (имхо) перетащить код из OnTimer в Thread.Execute и вызывать из OnTimer Thread.Create...
← →
Anatoly Podgoretsky (2003-03-19 15:49) [15]Style (19.03.03 13:48)
Если не вставить обработку сообщений, то не только остальные таймеры не будут обрабатываться но многое и другое.
AlexVit © (19.03.03 14:13)
Ты учти еще и следующее, что твоя обработка должна занимать места меньше, чем интервал таймера.
Может потоки в твоем случае и лишнее, тогда возможно и таймеры не нужны будут, можно будет обойтись другими методами, хотя бы sleep внутри потока или по другому.
← →
ki11er (2003-03-19 15:54) [16]
> Похоже, оптимальное решение (имхо) перетащить код из OnTimer
> в Thread.Execute и вызывать из OnTimer Thread.Create...
Если я правильно понял задачу, то сделал бы так:
для каждого типа обработки запустил поток.
На "холостом ходу" каждый из них ждет своего события.
Из соответствующего таймера устанавливается соответствующее событие (при этом нужный поток просыпается, выполняет, что нужно и снова засыпает).
← →
Style (2003-03-19 16:40) [17]>> Если не вставить обработку сообщений, то не только остальные таймеры не будут обрабатываться но многое и другое.
Но в одном потоке обработка сообщений ему не поможет.
ki11er >>
Наверно будет лучше так! А общение между нитямя осуществить через посылку сообщений (PostMessage)..
← →
Kent (2003-03-19 19:17) [18]А я бы, честно сказать, сделал бы так, отслеживал системное время и через определенные промежутки времени (если надо по расписанию) запускал бы для каждого из параллельных процессов свой поток, блокирование определенных однотипных потоков (если вдруг обработка одного из них затянулась и копия грозится повторно "обработать" :) таблицу) через мьютексы одноименные с таблицами или наборами таблиц.
Организация многопоточного доступа к БД замечательно показана в книге Тейксейры и Пачеко "Delphi 5 для профессиналов" (двухтомник).
Похожую проблему сам решал вышеуказанным методом, только вместо БД был набор файлов.
С уважением ко всем !!!
Страницы: 1 вся ветка
Текущий архив: 2003.03.31;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.007 c