![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ищу реализацию таймера в треде.
Дмитрий Белькевич © (2010-06-14 14:48:00)TTimer не работает, если управлять им из треда. Waitable Timer не имеет события (а нужно именно событие, не задержка). Скажите, видел ли кто реализацию Waitable Timer с генерацией события (как я себе представляю, Waitable Timer в отдельном треде).
Сергей М. (2010-06-17 17:24:00) [1]
> Timer Writer (17.06.10 17:20) [17]
Наверно я не понимаю)
Ну не дано мне понять нагромождение кода, лишенное смысла)
Timer Writer (2010-06-17 17:20:00) [2]
> Сергей М. © (17.06.10 16:50) [16]
Кто-то из нас не понимает смысла этого таймера. Убеждать и доказывать не буду.
Сергей М. (2010-06-17 16:50:00) [3]
> ожидание тика происходит в доп. потоке. Что тоже правильно
Ниразу не правильно, если обработка тика все равно вынесена в осн.поток.
Что толку ждать тик (а чего его ждать ? он все равно никуда не пропадет), если не гарантирована немедленная на него реакция ?
Timer Writer (2010-06-17 16:39:00) [4]
> Его с успехом заменяет SLEEP
Если Sleep ставить в основном потоке, то остановится интерфейс. Что, конечно, не годится.
А если ставить Sleep в отдельном потоке, то каким образом прервать этот Sleep?
Никаким. А это нужно при переустановке параметров таймера и в его деструкторе.
> обработка событий таймера у тебя все равно выполняется в осн.потоке.
И это правильно. А ожидание тика происходит в доп. потоке. Что тоже правильно.
Сергей М. (2010-06-17 16:32:00) [5]
> Timer Writer (17.06.10 16:30) [12]
Потому что обработка событий таймера у тебя все равно выполняется в осн.потоке.
Anatoly Podgoretsky (2010-06-17 16:32:00) [6]> Сергей М. (17.06.2010 16:09:11) [11]
Его с успехом заменяет SLEEP
Timer Writer (2010-06-17 16:30:00) [7]
> Сергей М. © (17.06.10 16:09) [11]
Почему?
Сергей М. (2010-06-17 16:09:00) [8]
> procedure TTimerThread.Execute;
> begin
> while not Terminated do
> if WaitForSingleObject(FEvent, FInterval) = WAIT_TIMEOUT
> then
> Synchronize(DoTimer)
> end;
>
Толку от такого "таймера в отдельном потоке" - что от 5-го колеса у телеги)
Timer Writer (2010-06-17 15:42:00) [9]Вот только что написанный класс - таймер в отдельном потоке (как раз для одного проекта потребовался). Но предупреждаю - еще не тестировался.
unit ThreadTimer;
interface
uses
Windows, Classes;
type
TTimerThread = class(TThread)
private
FEnabled: boolean;
FInterval: cardinal;
FEvent: THandle;
FOnTimer: TNotifyEvent;
procedure SetEnabled(const Value: boolean);
procedure SetInterval(const Value: cardinal);
procedure Stop;
procedure DoTimer;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: boolean; AInterval: cardinal = 1000);
destructor Destroy; override;
property Enabled: boolean read FEnabled write SetEnabled;
property Interval: cardinal read FInterval write SetInterval;
property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
end;
implementation
{ TTimerThread }
constructor TTimerThread.Create(CreateSuspended: boolean; AInterval: cardinal);
begin
inherited Create(True);
FInterval := AInterval;
FEvent := CreateEvent(nil, False, False, nil);
SetEnabled(not CreateSuspended)
end;
destructor TTimerThread.Destroy;
begin
Terminate;
Stop;
Resume;
if GetCurrentThreadId <> ThreadID then
WaitFor;
CloseHandle(FEvent);
inherited
end;
procedure TTimerThread.DoTimer;
begin
if FEnabled and Assigned(FOnTimer) then
FOnTimer(Self)
end;
procedure TTimerThread.Execute;
begin
while not Terminated do
if WaitForSingleObject(FEvent, FInterval) = WAIT_TIMEOUT then
Synchronize(DoTimer)
end;
procedure TTimerThread.SetEnabled(const Value: boolean);
begin
if FEnabled <> Value then
begin
Stop;
FEnabled := Value;
if FEnabled then
Resume
end
end;
procedure TTimerThread.SetInterval(const Value: cardinal);
begin
if FInterval <> Value then
begin
FInterval := Value;
if FEnabled then
begin
Stop;
SetEnabled(True)
end
end
end;
procedure TTimerThread.Stop;
begin
FEnabled := False;
SetEvent(FEvent);
while Suspended do
Resume;
Suspend
end;
end.
Германн (2010-06-15 00:52:00) [10]
> DVM © (15.06.10 00:03) [8]
Нечто подобное было в RxLib. TRxTimerList. Может и в JEDI есть. Не знаю, но возможно автору стоит проверить хоть он уже и сказал, что сделал на основе WinAPI SetTimer.
DVM (2010-06-15 00:03:00) [11]
> Дмитрий Белькевич
вот еще хороший материал по таймеру http://www.delphikingdom.com/asp/viewitem.asp?catalogid=434
Там и реализация
Дмитрий Белькевич (2010-06-14 16:22:00) [12]Всем спасибо, да.
Дмитрий Белькевич (2010-06-14 16:20:00) [13]
> Вот прямо так и говорит - я, таймер, не работаю, если мной
> управляют из треда.
Ага. Мессагу на экран выбрасывает :)
Сделал с помощью SetTimer.
Сергей М. (2010-06-14 15:49:00) [14]
> TTimer не работает, если управлять им из треда
Угу.
Вот прямо так и говорит - я, таймер, не работаю, если мной управляют из треда.
Rouse_ (2010-06-14 15:27:00) [15]А SetTimer с указанием TIMERPROC чем не устроил?
Дмитрий Белькевич (2010-06-14 15:20:00) [16]
> Сделайте в нити петлю сообщений и заработает ваш TTimer
С ним хитро. В 7-ке работало без вопросов. В 2010 - работает, только если enabled менять синхронно, т.е. делаю Synchronize, в нём - дёргаю enabled, всё работает. Но уже хотелось бы по-людски сделать.
Дмитрий Белькевич (2010-06-14 15:16:00) [17]Нашел таки...
http://www.google.com/codesearch/p?hl=ru#CxUs5Idmy2w/download/Stepper17.zip%7CVIUzRXe8mi0/StepperMotor%20Ver.1.7/src/StepperMotor.pas&q=CreateWaitableTimer%20lang:pascal
Не знаю, насколько рабочее, правда... Вроде бы лицензионных ограничений нет.
~AQUARIUS~ (2010-06-14 15:09:00) [18]Сделайте в нити петлю сообщений и заработает ваш TTimer