Re[3]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Denis_TST Россия www.transsys.ru
Дата: 12.11.03 19:58
Оценка: -2 :)
Здравствуйте, Slicer [Mirkwood], Вы писали:

D_T>>в потоке нельзя использовать таймеры

это смотря какие таймеры использовать, TTimer в потоке не прокатит
в вопросе же спрашивалось про него , а не про API функции
кроме того, как в этом примере добитьcя интервала срабатывания в 500 наносекунд?
SM>
SM>program Proof;
SM>var
SM>...
SM>  idThread:dword;
SM>begin
SM>  CreateThread(nil, 0, @Thread, nil, 0, idThread);
SM>  readln;
SM>end.
SM>

да, так конечно можно, но это IMHO извращениее,
если в потоке не используюся сообщения,
то цикл опроса сообщений — лишнее и IMHO это плохой стиль программирования
SM>Tested on FPC 1.0.10.

SM>Slicer
... << RSDN@Home 1.1.0 stable >>
Re[5]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.11.03 09:39
Оценка: 8 (1) +1
Здравствуйте, vtroitsk, Вы писали:
V>несовсем так.
V> есть поток.в нем Download (без всякой визуальщины... формы нет )
V> таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)
Неважно, где он объявлен. Если ты его создаешь внутри метода Execute, то все сообщения от таймера будут приезжать именно в этот поток. И он обязан делать message pump. А если создавать его за пределами метода Execute (можно даже в конструкторе треда, не только во внешнем коде), то сообщения таймера будут приезжать в другой поток (скорее всего в главный).
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.11.03 19:39
Оценка: 6 (1) +1
Здравствуйте, Slicer [Mirkwood], Вы писали:

SM>Значит, так, с потоками я не работал, по большому счету, а Дельфей под руками нет. Поэтому у меня не ответ, а вопрос. Когда мы создаем таймер, к какому окну дельфи его привязывает (see WinAPI SetTimer)? Подозреваю, что к Application

Нет. Создается специальное окно. UTSL:
  TTimer = class(TComponent)
  private
    FInterval: Cardinal;
    FWindowHandle: HWND;
    FOnTimer: TNotifyEvent;
    FEnabled: Boolean;
    procedure UpdateTimer;
    procedure SetEnabled(Value: Boolean);
    procedure SetInterval(Value: Cardinal);
    procedure SetOnTimer(Value: TNotifyEvent);
    procedure WndProc(var Msg: TMessage);
  protected
    procedure Timer; dynamic;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Enabled: Boolean read FEnabled write SetEnabled default True;
    property Interval: Cardinal read FInterval write SetInterval default 1000;
    property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
  end;
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
От: Denis_TST Россия www.transsys.ru
Дата: 11.11.03 21:01
Оценка: -2
Здравствуйте, vtroitsk, Вы писали:

V>общая схема:


V>как в потоке грамотоно создать таймер...


в потоке нельзя использовать таймеры , надо пользовться функциями ожидания
самый простой вариант :
 I:=1000*60*3; // 3 минуты
 Sleep(i);

но он не точный — время ожидания зависит от планировщика потоков (приоритета потоков итд )
для более точных интревалов надо использовать объект ядра "ожидаемый таймер" (WaitableTimer)
как уже отвечали выше.
вообще рекомндую почитать Рихтера "Windows для профессионалов", для такой задачи (многопоточная закачка)
IMHO это необходимо ...
... << RSDN@Home 1.1 beta 2 >>
Re[3]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 11.11.03 08:38
Оценка: +1
Ну, тогда получается, что если это окно создается в отдельном потоке,
то и сообщения новому окну идут в очередь этого потока, так ведь?

V>TMyThread.Execute
V>begin
V>  fd_Timer:=TMyTimer.Create(nil);
V>  fd_Timer.Enabled:=true;

V>    Download //моя процедура любящая  зависать надолго....

V>  fd_Timer.enabled:=false;
V>  fd_Timer.free;

V>end;


Мы чего хотим — чтобы сообщения от таймера обрабатывались, а в
отдельном потоке выполнялся Download. А чего написали? Чтобы в
отдельном потоке создавался таймер, а потом в нем же выполнялся
download. А кто будет сообщения от таймера проверять — они ведь
будут появляться в его же потоке?

Вариант:

Procedure StartDownload;
var T:TThread;
begin
  fd_Timer:=TMyTimer.Create(nil);
  fd_Timer.Enabled:=true;

  T:=TMyThread.Create(true);
  T.ChildTimer:=TMyTimer.Create(nil);
  T.ChildTimer.enabled:=nil;
  T.Resume();
  //А можно всю эту дребедень в конструктор передать, правда, 
придется новый конструктор писать
end;

Type
  TMyThread = class(TThread)
    .......
  ChildTimer :TMyTimer;
    .......
  end;

TMyThread.Execute
begin
  Download //моя процедура любящая  зависать надолго....
  ChildTimer.enabled:=false;
  ChildTimer.free;
end;


Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[3]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Аноним  
Дата: 15.11.03 08:10
Оценка: :)
Здравствуйте, Slicer [Mirkwood], Вы писали:


SM> if (M.Message=WM_TIMER) then writeln('WM_TIMER');


В потоке нельзя использовать writeln
Т.е., в данном случае, лучше WriteFile

--
С уважением, LVT.
Delphi. как грамотно создать и исп-ть Timer в Thread...
От: vtroitsk  
Дата: 10.11.03 15:15
Оценка:
общая схема:
------
есть программа.. многопоточная скачка с FTP
(не смейтесь... стандарт проги типа Getright не подходят — данные специфичые)
но в ходе работы потоков бывает связь с FTP впадает в глубокий зависон(я так понял вешается Data chanel при
передачи потока данных).
Есть идея перед началом работы потока поставить таймер с интервалом например 3 мин. если по истечении этого
интервала работа скачка все еще висит то kill ей ... , ... и поновой закачка идет.
------

как в потоке грамотоно создать таймер...

вот мой примерный код:

//-------------Timer desc--------
TMyTimer = class(TTimer)
public
constructor Create(AOwner: TComponent); override;
procedure Tick(Sender: TObject);
end;

constructor TMyTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Enabled:=false;
Interval:=5000;
OnTimer := Tick;
end;
procedure TMyTimer.Tick(Sender: TObject);
begin

//даем сигнал на отбой Download
Enabled:=false
end;
//-------------Thread desc--------
TMyThread = class(TThread)
.......
fd_Timer :TMyTimer;
.......
end;
//--------------------------------

//=================
//--program body---
//=================

...
TMyThread.Execute
begin
fd_Timer:=TMyTimer.Create(nil);
fd_Timer.Enabled:=true;

Download //моя процедура любящая зависать надолго....

fd_Timer.enabled:=false;
fd_Timer.free;

end;
...
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
От: Аноним  
Дата: 10.11.03 15:35
Оценка:
Здравствуйте, vtroitsk, Вы писали:

V>общая схема:

V>------
V> есть программа.. многопоточная скачка с FTP
V> (не смейтесь... стандарт проги типа Getright не подходят — данные специфичые)
ХА ХА ХА ХО ХО ...


V>как в потоке грамотоно создать таймер...


Можно попробовать SetTimer внутри потока и в качестве ID таймера задать Handle потока.
Мессаги все равно будет получать основной поток, при получении мессаги от таймера — грохать поток с ID таймера.
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 10.11.03 15:35
Оценка:
Значит, так, с потоками я не работал, по большому счету, а Дельфей под руками нет. Поэтому у меня не ответ, а вопрос. Когда мы создаем таймер, к какому окну дельфи его привязывает (see WinAPI SetTimer)? Подозреваю, что к Application

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.11.03 16:44
Оценка:
Здравствуйте, vtroitsk, Вы писали:

SetWaitableTimer
http://www.rsdn.ru/article/baseserv/threadpool.xml#XSLTSECTION132145120120
Автор(ы): Алексей Ширшов
Дата: 03.08.2003
Статья посвящена системным механизмам, организующим (или помогающим организовать) пул потоков. Рассматриваются базовые, универсальные сервисы, с помощью которых можно реализовывать серверы для любых доступных механизмов взаимодействия сервера и клиента: сокеты, именованные каналы (named pipes), почтовые ящики (mailslots) и проч.
и солнце б утром не вставало, когда бы не было меня
Re[4]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: vtroitsk  
Дата: 11.11.03 09:17
Оценка:
...
SM>Мы чего хотим — чтобы сообщения от таймера обрабатывались, а в
SM>отдельном потоке выполнялся Download. А чего написали? Чтобы в
SM>отдельном потоке создавался таймер, а потом в нем же выполнялся
SM>download. А кто будет сообщения от таймера проверять — они ведь
SM>будут появляться в его же потоке?
..

несовсем так.
есть поток.в нем Download (без всякой визуальщины... формы нет )
таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)
Re[5]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 11.11.03 09:25
Оценка:
Здравствуйте, vtroitsk, Вы писали:

V>несовсем так.

V> есть поток.в нем Download (без всякой визуальщины... формы нет )
V> таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)

Чур меня! Это как — таймер как переменная класса потока?!
И зачем тебе таймер обязательно в этот поток запихивать? Определист — доп. поток тебе нужен чтобы в нем производить Download или чтобы в нем отображать прогресс? По условию твоей задачи (т.е. визуальное "неповисание") это должны быть разные потоки!

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[5]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: mrhru Россия  
Дата: 11.11.03 09:31
Оценка:
Здравствуйте, vtroitsk, Вы писали:

V>...

SM>>Мы чего хотим — чтобы сообщения от таймера обрабатывались, а в
SM>>отдельном потоке выполнялся Download. А чего написали? Чтобы в
SM>>отдельном потоке создавался таймер, а потом в нем же выполнялся
SM>>download. А кто будет сообщения от таймера проверять — они ведь
SM>>будут появляться в его же потоке?
V>..

V>несовсем так.

V> есть поток.в нем Download (без всякой визуальщины... формы нет )
V> таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)

Гм. А зачем там вообще таймер?
Для его работы, в Download надо будет периодически вызывать:
— что-то типа PeekMessages — для обработки сообщений для таймера
— проверять состояние таймера.

Не проще ли в начале Download получить текущее время (GetTickCount) и дальше сверяться с ним?
Re[6]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Hacker_Delphi Россия  
Дата: 11.11.03 10:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Неважно, где он объявлен. Если ты его создаешь внутри метода Execute, то все сообщения от таймера будут приезжать именно в этот поток. И он обязан делать message pump. А если создавать его за пределами метода Execute (можно даже в конструкторе треда, не только во внешнем коде), то сообщения таймера будут приезжать в другой поток (скорее всего в главный).

ну, если быть точным, то в вызывающий а так — все верно...
... << RSDN@Home 1.1.0 stable >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[2]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 11.11.03 23:22
Оценка:
D_T>в потоке нельзя использовать таймеры
Будь добр, объясни, почему?

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
От: defrag  
Дата: 12.11.03 09:22
Оценка:
Для работы с сетью в потоке используй блокирующий тип сокета, и поток TWinSocketStream
У него есть функция WaitForData с указанием тайм-аута.
Если данные не пришли, то можешь завершать поток
если пришли — сам знаешь что с ними делать.
Re[2]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 12.11.03 11:58
Оценка:
D_T>в потоке нельзя использовать таймеры

program Proof;

{$APPTYPE CONSOLE}

uses windows;

function Thread(Parameter:pointer):dword; stdcall;
var idTimer:dword;
    M:TMsg;
begin
  idTimer:=SetTimer(0,0,1000,nil);
  while integer(GetMessage(M,0,0,0))>0 do
    begin
      TranslateMessage(M);
      if (M.Message=WM_TIMER) then writeln('WM_TIMER');
      DispatchMessage(M);
    end;
  KillTimer(0,idTimer);
  result:=0;
end;

var
  idThread:dword;
begin
  CreateThread(nil, 0, @Thread, nil, 0, idThread);
  readln;
end.


Tested on FPC 1.0.10.

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[4]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Forint Украина  
Дата: 13.11.03 10:20
Оценка:
Это что за наносекутды такие? Я в своё время мили секунды не смог нормально отследить...
... << RSDN@Home 1.0 beta 7a >>
Re[4]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 13.11.03 11:04
Оценка:
Не верю про TTimer А точные таимеры — это вообще отдельная тема, и затрагивалась она неоднократно.

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[4]: Delphi. как грамотно создать и исп-ть Timer в Thr
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 13.11.03 17:34
Оценка:
Здравствуйте, Denis_TST, Вы писали:

D_T>то цикл опроса сообщений — лишнее и IMHO это плохой стиль программирования


А позволить кому-то загадить твоему потоку очередь сообщений PostThreadMessage-ом (ведь, выходит, ее никто и разгребать не будет, раз нет message-pump) — и вовсе никудышный стиль программирования Разве что поток таков, что очередь для него не создается вообще.

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.