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

Вниз

В потоке не вызывается событие ttimer (запутался в потоках)   Найти похожие ветки 

 
msgipss   (2005-09-15 12:06) [0]

Здравствуйте знатоки, помогите пожалуйста понять ситуацию,
Есть тестовая форма, на ней кнопка, по кнопке создаю, запускаю Thread, в этом Thread"е создаю запускаю еще 1 Thread, в последнем треде есть ttimer, так вот событие этого таймера не могу получить, не срабоатывает оно, в первом пробовал - срабатывает без проблем.


 
Digitman ©   (2005-09-15 12:09) [1]

у тебя ошибка в программе


 
Reindeer Moss Eater ©   (2005-09-15 12:13) [2]

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


 
msgipss   (2005-09-15 12:51) [3]

разрешите вам показать пример кода, Digitman только сильно не бей:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls;

type
 Thread2 = class(TThread)
 private
   dTimer: TTimer;
 protected
   procedure Execute; override;  // Основной метод потока
   procedure OnTimerClose(Sender: TObject);  // обработка таймера выполнения события
  public
   constructor Create(bStart:Boolean);  // Пишем свой конструктор Create
 end;

 Thread1 = class(TThread)
 private
   dTimer: TTimer;
   thread:thread2;
 protected
   procedure Execute; override;  // Основной метод потока
   procedure OnTimerClose(Sender: TObject);  // обработка таймера выполнения события
  public
   constructor Create(bStart:Boolean);  // Пишем свой конструктор Create
 end;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
   thread:Thread1;
 public
   { Public declarations }
 end;
var
 Form1: TForm1;

implementation

{$R *.dfm}

constructor Thread1.Create(bStart:Boolean);  // Пишем свой конструктор Create
begin
 FreeOnTerminate := true;    // После завершения выполнения метода Execute разрушать объект потока
 dTimer:= TTimer.Create(nil);
 if bStart then inherited Create(False)   // создать задачу и сразу запустить
   else inherited Create(True);    // создать приостановленную задачу
end;
procedure Thread1.Execute;
begin
  thread:=Thread2.Create(true);
  dTimer.OnTimer:=OnTimerClose;
  dTimer.Interval:=3000;
  dTimer.Enabled:=true;

  while not Terminated do
  begin
     sleep(1000);
  end;
end;
procedure Thread1.OnTimerClose(Sender: TObject);  // обработка таймера выполнения события
begin
   showmessage("Thread 1");
end;

constructor Thread2.Create(bStart:Boolean);  // Пишем свой конструктор Create
begin
 FreeOnTerminate := true;    // После завершения выполнения метода Execute разрушать объект потока
 dTimer:= TTimer.Create(nil);
 if bStart then inherited Create(False)   // создать задачу и сразу запустить
   else inherited Create(True);    // создать приостановленную задачу
end;
procedure Thread2.Execute;
begin
  dTimer.OnTimer:=OnTimerClose;
  dTimer.Interval:=3000;
  dTimer.Enabled:=true;

  while not Terminated do
  begin
     sleep(1000);
  end;
end;
procedure Thread2.OnTimerClose(Sender: TObject);  // обработка таймера выполнения события
begin
   showmessage("Thread 2");
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  thread:=Thread1.Create(true);
end;

end.


 
Smithson   (2005-09-15 13:32) [4]

А зачем в потоке таймер? Объясни плиз.


 
Digitman ©   (2005-09-15 13:44) [5]

constructor Thread2.Create(bStart:Boolean);  // Пишем свой конструктор Create
begin
..
dTimer:= TTimer.Create(nil); //этот таймер создан в контексте доп.потока 1, который никак не обрабатывает сообщения окну созданного в нем таймера
..
end;


 
msgipss   (2005-09-15 13:59) [6]

Smithson: А зачем в потоке таймер? Объясни плиз.
иногда нужно менять логику потока через опр.врем.интервал,
согласен можно и без таймера..

Digitman ©: этот таймер создан в контексте доп.потока 1, который никак не обрабатывает сообщения окну созданного в нем таймера
а как запустить таймер в контексте самого потока, если первый поток создает несколько десятков вторых ?


 
msgipss   (2005-09-15 14:15) [7]

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


 
Reindeer Moss Eater ©   (2005-09-15 14:21) [8]

Что делает поток когда ждет тики таймера?
Ничего не делает.
Отсюда вывод, что пока таймер не натикал нужное кол-во времени - поток не нужен вообще.


 
Digitman ©   (2005-09-15 14:24) [9]


> как запустить таймер в контексте самого потока

создать и запустить объект-таймер в теле метода Execute() того самого потока, который заинтересован в событиях этого таймера.


> с обработкой будут проблемы


любые проблемы решаемы.


> или обрабатывать через основной - да ?


нет.

основной ответственен ТОЛЬКО за обработку событий тех таймеров. который созданы в его контексте

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


 
msgipss   (2005-09-15 14:44) [10]

Reindeer Moss Eater: Что делает поток когда ждет тики таймера?
не совсем так, пока таймер не натикал исполняется другая логика..

Digitman © а тогда не скромный вопрос - как можно обработать событие, например на выше указанном тесте?


 
Reindeer Moss Eater ©   (2005-09-15 14:57) [11]

>не совсем так, пока таймер не натикал исполняется другая логика..

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


 
Digitman ©   (2005-09-15 15:07) [12]


> msgipss   (15.09.05 14:44) [10]


> как можно обработать событие, например на выше указанном
> тесте?


обычным образом :

procedure ThreadN.Execute;
var
 Msg: TMsg;
begin
try
 dTimer := TTimer.Create(nil);
 try
 dTimer.OnTimer:=OnTimerClose;
 dTimer.Interval:=3000;
 dTimer.Enabled:=true;
 while not Terminated and PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
  begin
    DispatchMessage(Msg);
    sleep(1);
  end;
finally
 dTimer.Free;
end;
except
 on e: exception do
   MessageBox(0, PChar(e.Classname + " " e.Message), PChar("Исключительная ситуация в объекте-потоке класса " + Self.ClassName), mb_ok or mb_setforeground);
end;
end;

procedure ThreadN.OnTimerClose(Sender: TObject);
var
 s: String;
begin
 s := "Инициатор события - объект класса " + Sender.ClassName;
 if GetCurrentThreadId = MainThreadId then
   showmessage(s)
else
  MessageBox(0, PChar(s), "", mb_ok or mb_setforeground);
if Sender is TThread then
  TThread(Sender).Terminate;
end;


 
Digitman ©   (2005-09-15 15:09) [13]

вру ..

while not Terminated do
 begin
  if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
    DispatchMessage(Msg);
  sleep(1);
 end;


 
msgipss   (2005-09-16 06:12) [14]

Digitman, спасибо - сел в отладку с книжкой 8)


 
Defunct ©   (2005-09-16 06:30) [15]

господа..вчастности msgipss...
если вопрос только в таймере, то почему бы вместо TTimer не воспользоватья функцией GetTickCount либо в крайнем случае функцией Now..

Thread1 = class(TThread)
private
  fEventTime : Cardinal;

  function SetTimer( const Interval:Cardinal);
  procedure ItMustBeSynchronized;
protected
  procedure Execute; override;  // Основной метод потока
  procedure SomeEvent(Sender: TObject);  // обработка таймера выполнения события
end;

procedure Thread1.SetTimer;
begin
 fEventTime := GetTickCount + Interval;
end;

procedure Thread1.Execute;
begin
 SetTimer( 3000 );

 while not Terminated do
 begin
    sleep(100);
    if GetTickCount > fEventInterval then
    begin
       SomeEvent( Self );
       SetTimer( 3000 );
    end;
 end;

end;

procedure Thread1.ItMustBeSynchronized;
begin
  ShowMessage( "Thread1" );
end;

procedure Thread1.SomeEvent(Sender: TObject);  // обработка таймера выполнения события
begin
  Synchronize( ItMustBeSynchronized );
end;


 
msgipss   (2005-09-16 07:41) [16]

Defunct:
я ttimer не использую, время считаю сам (можно и так как у Вас),
ttimer попробовал - не получилось, стало любопытно - начал задавать глупые вопросы, ответы получил (спасибо участникам ветки) закрепил теорией - теперь довольный 8)



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

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

Наверх





Память: 0.5 MB
Время: 0.014 c
4-1124101875
dddim
2005-08-15 14:31
2005.10.09
SW_HIDE


14-1127306421
oldman
2005-09-21 16:40
2005.10.09
У кого стоит 1С? Проблемку поймал...


14-1127211115
SlyFox
2005-09-20 14:11
2005.10.09
UNIX & C: откровения :)


1-1126864825
nikolas
2005-09-16 14:00
2005.10.09
TPop3Cli


3-1124738990
Cheaterr
2005-08-22 23:29
2005.10.09
Сравнение остатков с мин. размером кол-во материала (Access)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский