Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

таймер в потоке [D6, D7, Win2k]


Kaginava ©   (2004-07-09 09:16:00) 

Всем привет !!
Подскажите как правильно в отдельном потоке запустить таймер ?
я пробовал так
constructor mayTr.Create(interval:integer);
 begin
    inherited Create(True);
    FreeOnTerminate := True;
    Self.Priority := tpHighest;
    timer:=TTimer.Create(nil);
    timer.Interval:=interval;
    timer.OnTimer:= OnTimerSt;
    timer.Enabled:=true;
    resume;

 end;


если в конструкторе потока запустить таймер то что тогда в
методе Execute делать ?


ZiRoCool   (2004-07-09 12:40:00) [1]

т.к. событие пустое, ничего не произойдёт, и задержка будет именно столько сколько указано


ZiRoCool   (2004-07-09 12:39:00) [2]

может я и не прав но вроде паузу лучше делать через WaitSingleObject, вот так:

var h: Thandle;
....
begin
....
   //Приостанавливаемся
   h:=CreateEvent(nil,true,false,'');
   WaitForSingleObject(h, 1000);
   CloseHandle(h);
....
end;


Kaginava   (2004-07-09 12:23:00) [3]

а почему до потери пульса если указано 1000мс ?


Digitman   (2004-07-09 12:20:00) [4]


> может кто объяснит почему ?


потому что "// приостанавливаемся" и ждем неизвестно чего до потери пульса


Kaginava   (2004-07-09 11:56:00) [5]

пробовал так :
procedure TSomeThread.Execute;
begin
while not Terminated do
  begin
    ...
    // здесь выполняем какие-то действия
    ...
    // приостанавливаемся
    Sleep(1000);
  end;
end;


почему то действие в этом цикле выполняутся один раз при старте
сервиса и все , может кто объяснит почему ?


han_malign   (2004-07-09 10:26:00) [6]

>А вот за это:
>Self.Priority := tpHighest;
>надо бить по рукам.
- а ничего не будет - у процесса-то приоритет обычный. Другое дело что сервис не будет отвечать на запросы(если sleep убрать), но это уже другие грабли...


Digitman   (2004-07-09 10:23:00) [7]

TJobService = class(TService)
...
 private
...
   procedure MsgSvcCtrl(var Message: TMessage); message SM_CONTROL;
...
 end;

...

procedure TJobService.ServiceExecute(Sender: TService);
var
 Msg: TMsg;
begin
 while not Terminated do
   begin
     WaitMessage;
     if PeekMessage(Msg, 0, SM_CONTROL, SM_CONTROL, PM_REMOVE) then
       Dispatch(Msg.Message)
     else
       ServiceThread.ProcessRequests(False);
   end;
end;

procedure TJobService.MsgSvcCtrl(var Message: TMessage);
begin
...
end;

отныне сервис оперативно реагирует как на команды сервис-менеджера так и на польз.сообщения SM_CONTROL, посланные трэду сервиса кем бы то ни было откуда бы то ни было вызовом PostThreadMessage()


Kaginava   (2004-07-09 10:20:00) [8]

да, действительно таймер мне не нужен, я сам себя запутал.
Всем спасибо :))


Петров Денис   (2004-07-09 10:19:00) [9]

А вот за это:


Self.Priority := tpHighest;


надо бить по рукам.


Петров Денис   (2004-07-09 10:18:00) [10]

> Kaginava   (09.07.04 09:31) [2]

Таймер тебе точно не нужен. Реализуй что-то вроде этого:


procedure TSomeThread.Execute;
begin
 while not Terminated do
   begin
     ...
     // здесь выполняем какие-то действия
     ...
     // приостанавливаемся
     Sleep(1000);
   end;
end;


Кусок кода между begin и Sleep будет отрабатывать с периодичностью в 1 сек.


Digitman   (2004-07-09 10:11:00) [11]


> Kaginava   (09.07.04 09:31) [2]


> чтобы сервис отвечал на команды сервисменеджера основные
> действия должны выполняться в отдельном потоке, может я
> не прав.


не прав

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


Тимохов   (2004-07-09 09:57:00) [12]


> Kaginava   (09.07.04 09:16)  

конструктор класса TThread выполнятся в контексте вызывающего потока, поэтому к execute это никакого отношения не имеет.


> если в конструкторе потока запустить таймер то что тогда
> в
> методе Execute делать ?


покажите код тела execute тогда и будет понятно, что делать.


Fay   (2004-07-09 09:38:00) [13]

Таймер - объект ядра. Ему пофинг твои потоки. Описатель таймера можно хранить как данные основного или доп. потока. Куда хочешь - туда и суй. Всё равно получишь результат. 8)


Kaginava   (2004-07-09 09:36:00) [14]

спасибо так и попробу сделать.


Рамиль   (2004-07-09 09:33:00) [15]

Так поставь таймер в основном потоке, и запускай по нему дополнительный, сервис будет обрабатывать сообщения.


Kaginava   (2004-07-09 09:31:00) [16]

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


KSergey   (2004-07-09 09:19:00) [17]

1.Зачем в потоке таймер? Там есть свои средства временного приостановления потока, если уж так надо. На WaitSingleObject и т.п. (это как раз и делать в Execute).
2.Self.Priority := tpHighest; - а хоршо ли это? да и Self тут всяко ни к чему.


Наверх

Титульная страница Поиск, карта сайта Написать письмо