Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Timer1


Автор: Молоток 16.4.2008, 15:59
Вот меня терзает задача уже несколько дней:
у меня есть Timer1 и он конкретно выполняет действия с интервалом.
Как мне сделать что бы таймер выполнял рязные действия с разным интервалом, при этом на форме юзался только Один компонент таймера.
Спасибо!

Автор: MetalFan 16.4.2008, 16:31
ишь какой! и рыбку съесть и сковородку не помыть.
так меня интервалы динамически

Автор: Молоток 16.4.2008, 16:35
MetalFan, Ну а толку ?
Если у меня допустим на 1 таймере надо выполнить 20 задач.
 smile 

Автор: 1Andrey1 16.4.2008, 17:05
я конечно не совсем понимаю зачем нужен такой изврат... но как вариант сделать чтобы таймер тикал чаще, в OnTimer считать количество тиков и выполнять каждое действие через определенное количество тиков, для каждого события - своё 

Автор: ama_kid 16.4.2008, 18:16
Цитата(Молоток @  16.4.2008,  16:35 Найти цитируемый пост)
Если у меня допустим на 1 таймере надо выполнить 20 задач.
меняй динамически обработчик таймера

Автор: MetalFan 16.4.2008, 22:31
Цитата(Молоток @  16.4.2008,  16:35 Найти цитируемый пост)
Если у меня допустим на 1 таймере надо выполнить 20 задач.

одновременно? невозможно

Автор: Poseidon 17.4.2008, 09:41
Вместо TTimer используй TRxTimerList из библиотеки RxLib.

Цитата
Компонента предназначена для вызова пользовательских методов для обработчки события через заданные промежутки времени. Компонента поддерживает функциональность, аналогичную компоненте TTimer, но позволяет использовать один таймер Windows для всей очереди событий, хранящейся в списке Events (элементы типа TRxTimerEvent), сохраняя таким образом системные ресурсы, особенно в 16-битных приложениях. Каждое событие в очереди может быть активным или неактивным (свойство Enabled). Интервал вызова обработчиков задается в миллисекундах и имеет тип Longint, т.е. не имеет ограничения на длину интервала таймера Windows в 65535 мсек. 

Вы можете создавать события в дизайнере с помощью редактора компоненты TRxTimerList. Любое событие может быть "однократным", т.е. после одного его срабатывания через заданное время оно становится неактивным (в зависимости от значения свойства Cycled). 

Автор: Молоток 17.4.2008, 09:50
Poseidon, Спасибо!
1Andrey1,  Также спасибо интересная идея.

Автор: mmvds 17.4.2008, 10:24
Находим наибольший общий делитель из всех интервалов выполнения задач, устанавливаем интервал таймера таким.

Например нужно чтоб задачи выполнялись каждые 1000, 2000, 3000 мс 
НОД(1000,2000,3000)=1000 
ставим интервал таймера 1000.
Далее заводим счетчик тактов (целочисленная переменная), когда он без остатка делится на нужный интервал/нод выполняем нужное действие для этого интервала.

Пример:
Код

procedure TForm1.Timer1Timer(Sender: TObject);
begin
i:=i+Timer1.Interval;
if (i mod 1000/1000) =0 then
  begin
  {Делаем то, что нужно для таймера с интервалом 1000}
  end;
if (i mod 2000/1000) =0 then
  begin
  {Делаем то, что нужно для таймера с интервалом 2000}
  end;
if (i mod 3000/1000) =0 then
  begin
  {Делаем то, что нужно для таймера с интервалом 3000}
  end;
end;

Автор: Poseidon 17.4.2008, 10:29
mmvds, только вот проблема с ограниченностью i. Какого бы типа она не была, все-равно этот тип имеет максимально-допустимое значение. А если программе нужно работать день? А если неделю? А если серверное приложение и месяцами нужно "пахать"? Ну ты понял... smile

Автор: mmvds 17.4.2008, 10:44
integer хватит на 2^31/1000/60/60/24 = приблизительно 25 дней это если интервал 1мс поставить smile
ну хорошо, добавим в конец обнуление после 2 млрд итераций, кстати в первой строчке у меня ошибка была 
вместо i:=i+Timer1.Interval; надо i:=i+1;
Код

procedure TForm1.Timer1Timer(Sender: TObject);
begin
i:=i+1;
if (i mod 1000/1000) =0 then
  begin
  {Делаем то, что нужно для таймера с интервалом 1000}
  end;
if (i mod 2000/1000) =0 then
  begin
  {Делаем то, что нужно для таймера с интервалом 2000}
  end;
if (i mod 3000/1000) =0 then
  begin
  {Делаем то, что нужно для таймера с интервалом 3000}
  end;
end;
if i>=2000000000 then i:=0;

Автор: Poseidon 17.4.2008, 10:55
Цитата(mmvds @  17.4.2008,  10:44 Найти цитируемый пост)
надо i:=i+1;
inc(i) smile

Цитата(mmvds @  17.4.2008,  10:44 Найти цитируемый пост)
кстати в первой строчке у меня ошибка была вместо i:=i+Timer1.Interval; надо i:=i+1;
Ну тогда уже и 1000/1000 можно не писать, а просто 1 ставить.

Короче, оффтоп. Харэ smile

Автор: mmvds 17.4.2008, 11:16
1000/1000 это для наглядности нужный интервал/нод, а i:=i+Timer1.Interval; действительно ошибка, т.к. 1000 mod 2 =0 а в первую итерацию операции для интервала 2000 не должны выполняться, так что никакого оффтопа

Автор: Молоток 17.4.2008, 13:27
Poseidon, Мужики спасибо огромное много чего понел:
А если вот зачада так стоит:
Денамический таймер:
Я в листбокс  добовляю зачдачу например cmd.exe /C start index.bat 
Далие Задаю задачу cmd.exe /C start index2.bat 
И так далие до безконечности.
Как сделать что бы бежало в цикле и проверяло ?
Спасибо. 
PS данные о задачах хранятся в реестре: тойсть есть переменная с интервалом и параметрами задачи.
Как сделать что бы это работало всё в цикле.
Спасибо!

Автор: Antony41 14.2.2013, 10:19
создай отдельный поток в onExecute потока
Код

whle not Terminated do
   doWorking;

и обращайся через синхронизацию к лист боксу

Код

procedure doWorking;
var
   I: integer;
   LB: ^TListBox;
   s: string;
begin
   LB := @Form1.ListBox1;
  for I := 0 to LB.Count - 1 do
    begin
      Synchronize(
         procedure 
            begin
              S := LB^.Items[I];
              //обрабатываем строку S
              //короче тут что хочешь можно делать с ней.
              //потом допустим отправляешь на обработку эту строку
              Processing(S);
            end;
      )
    end;
  
end;


Добавлено @ 10:20
написал находу так что может есть ошибки

Добавлено @ 10:23
еще можно в основном потоке, но я бы сделал всё таки в отдельном
Код

while True do
begin
  Application.ProcessMessages;
  for I := 0 to ListBox.Count - 1 do
    begin
    //тоже самое что и в потоке
    end;
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)