Delphi не работают таймеры
Добрый день. Пишу свой компонент со встроенным таймером. Задача такая, нужно поставить на событие таймера процедуру моего компонента. В дебаггере смотрю FTimer.OnTimer присваивается адрес процедуры но событие не срабатывает.
Привожу полный текст модуля.
// Клиент на основе TClientSocket с проверкой получения данных и ведения истории в базе данных
unit DBClientSocket;
uses
SysUtils, Classes, ScktComp, ExtCtrls, Protocol;
type
TDBClientSocket = class(TClientSocket)
private
FTimeOut:integer; // Время ожидания подтверждения
FTimer:TTimer;
FTimeIsOut:boolean; // Сигнализирует о завершении времени на таймаут
FDataReceived:boolean; // Сигнализирует об успешном получении данных
FTimeIsOutOnTimer:TNotifyEvent;
procedure TimeIsOutOnTimer(Sender:TObject);
// Установка свойств
procedure SetTimeOut (const Value: integer);
procedure SetTimer (const Value: TTimer);
protected
function Waiting:TSendResult;
public
constructor Create(AOwner:TComponent);override;
function SendTextAndWait(Text:string):TSendResult;virtual; // Отсылает данные и ждет подтверждения
published
property TimeOut:integer read FTimeOut write SetTimeOut;
property Timer:TTimer read FTimer write SetTimer;
end;
procedure Register;
begin
RegisterComponents(«My», [TDBClientSocket]);
end;
// Конструктор
constructor TDBClientSocket.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FTimer := TTimer.Create(Self);
FTimer.Name:=»Timer1″;
FTimer.Enabled := False;
FTimeIsOutOnTimer:=TimeIsOutOnTimer;
end;
// Сигнал о том что время вышло
procedure TDBClientSocket.TimeIsOutOnTimer(Sender:TObject);
begin
FTimeIsOut:=true;
end;
// Функция ожидания
function TDBClientSocket.Waiting:TSendResult;
begin
// Устанавливаем таймер
if FTimer=nil then
begin
Result:=srWithoutWait;
Exit;
end;
FTimer.Interval:=FTimeOut;
FTimeIsOut:=false;
FTimer.OnTimer:=FTimeIsOutOnTimer;
FTimer.Enabled:=true;
// FDataReceived:=true;
// Ждем подтверждения или окончания таймаута
while (not FTimeIsOut) and (not FDataReceived) do
begin < TODO : Сделать ожидание таймаута >
end;
// Определяем результат и останавливаем таймер
if FDataReceived then Result:=srOk;
if FTimeIsOut then Result:=srTimeOut;
FTimer.Enabled:=false;
end;
// Отсылка данных с ожиданием подтверждения
function TDBClientSocket.SendTextAndWait(Text:string):TSendResult;
begin
// Посылаем текcт
Socket.SendText(Text);
Result:=Waiting;
end;
// Установка свойств —————————
procedure TDBClientSocket.SetTimeOut (const Value: integer);
begin
FTimeOut:=Value;
end;
procedure TDBClientSocket.SetTimer (const Value: TTimer);
begin
// if Value<>nil then
// FTimer.Assign(Value);
end;
← →
MBo © ( 2004-07-07 15:19 ) [1]
Неплохо было бы просмотреть этот форум чуть ниже.
← →
RagE © ( 2004-07-07 15:35 ) [2]
Дело в том что смотрел. Не работает. В том случае там событие на таймер задается как property. В моем случае нужно чтобы оно было определено в компоненте и пользователь не догадывался даже о таком.
← →
MBo © ( 2004-07-07 15:50 ) [3]
событие таймера связано НЕ с методом TimeIsOutOnTimer, а с переменной FTimeIsOutOnTimer, которая, собственно говоря, никуда не указывает.
Кроме того, настораживает, мягко говоря, метод ожидания.
← →
RagE © ( 2004-07-07 15:59 ) [4]
[3]
FTimeIsOutOnTimer:=TimeIsOutOnTimer;
Пробовал и FTimer.OnTime:=TimeIsOutOnTimer;
Метод ожидания такой что когда сработает таймер переменная YimeIsOut установитя в true и цикл прекратится. Вобщем то здесь он не важен. Все равно он будет не такой. Мне важно чтобы событие таймера срабатывало.
И такой еще вопрос возможно ли прямо в компоненте на событие OnRead установить свою процедуру опять же из компонента. Чтобы когда прийдут данные вызвался не событие пользователя а мое, которое уже потом и будет вызывать событие пользователя?
> такой еще вопрос возможно ли прямо в компоненте на событие OnRead установить свою процедуру опять же из компонента. Чтобы когда прийдут данные вызвался не событие пользователя а мое, которое уже потом и будет вызывать событие пользователя?
Так обычно и делается — в нужном месте вызывается (обычно динамический) метод, в котором делается нужная работа, и выполняется
if Assigned(FOnSomeEvent) then
FOnSomeEvent(Self[,ParamList]);
А вообще рекомендую скачать компонент CPort Dejan Crnila. Он для работы с компортом (с сокетами я просто не работал и не знаю, что посоветовать) и разобраться в логике работы — там сделано весьма грамотно.
← →
RagE © ( 2004-07-08 09:40 ) [6]
Ты меня не так понял. Про
if Assigned(FOnSomeEvent) then
FOnSomeEvent(Self[,ParamList]);
я знаю. Мне вот что нужно. У класса есть событие OnRead. мне нужно что то типа того что Class.OnRead:=Class.MyEvent;
Вобщем то пока я это дело сделал путем изменения исходника компонента
← →
RagE © ( 2004-07-08 09:41 ) [7]
Ну вобщем то о главном. Таймер то не работает.
← →
RagE © ( 2004-07-08 11:25 ) [8]
Все вопрос закрыт. Для тех кому интересен ответ: в цикле нужно вставлять ProcessMessages
← →
MBo © ( 2004-07-08 12:18 ) [9]
>RagE © (08.07.04 11:25) [8]
>ответ: в цикле нужно вставлять ProcessMessages
>MBo © (07.07.04 15:50) [3]
>Кроме того, настораживает, мягко говоря, метод ожидания.
Я не просто так ведь это написал — у тебя получается, что главный поток приложения, в котором крутится этот цикл, бесполезно кушает ресурсы процессора. ProcessMessages «оживляет» систему, но всех проблем не решает.
А вот в рекомендованном компоненте, например, запускается дополнительный поток с использованием Wait-функций — он спит себе, пока не случится событие, и никому не мешает.
Источник
Delphi не работают таймеры
Регистрация на форуме тут, о проблемах пишите сюда — alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль
| Регистрация Здравствуйте, помогите оптимизировать код. Алгоритм. memo заменю на tstringlist, вот этот блок бы оптимизировать, тут идет парсинг справа на лево, сам не смог( | |||||
а не подскажите, почему у меня таймер не срабатывает? |
Потому что мат. часть по синхронизации не выучена. Нельзя обращаться к компонентам и классам и другим формам из потока, без синхронизации.
Таймер не работает потому что поток к моменту срабатывания уже умер, либо в cod передан мусор. Все.
Потому что мат. часть по синхронизации не выучена. Нельзя обращаться к компонентам и классам и другим формам из потока, без синхронизации.
Таймер не работает потому что поток к моменту срабатывания уже умер, либо в cod передан мусор. Все.
Источник
Delphi не работают таймеры
fanlis
Это особенность Windows таймер на сообщениях работает как захочется левой пятки ведущего разработчика майкрософт.
С деланно это для оптимизации работы системы в сторону энергопотребления. В параллели на одном ядре у вас крутиться много программ. Чем меньше раз сработает таймер тем меньше времени съест ваше приложение и его можно будет потратить на остальные приложения. С ростом памяти стало больше приложений и в современных ОС таймер этот притормаживается программно.
Показания таймера на сообщениях(стандартный дельфийский). Зависит от числа запущенных программ. производительности вашего процессора и числа ядер. А также от разных ОС и более того от того главный поток или побочный. В побочном быстрее в 2 раза.
Для игр стоит использовать мультимедийный таймер. Он уже будет гарантированно работать с точностью 15,16 мс. И при настройке системы 1 мс.
timeGetTime, timeKillEvent, and timeSetEvent
timeBeginPeriod(1); // Устанавливаем время срабатывания мультимидийного таймера в 1мс
Этот параметр влияет на все программы в ОС. Так что не удивляйтесь если другая программа сделала это раньше вас.
Arigato
А ваш пример неверный так как вы используете менее точный таймер чем ТС.
GetTickCount — всегда даёт гранулярность 15.16 мс
QueryPerformanceFrequency — как повезёт но обычно либо 3 579 545 Гц либо 14 318 180 Гц либо порядка 2,4 ГГц
fanlis
При большой загрузки ОС может переносить программу с ядра на ядро и у вас будут разные значения QueryPerformanceCounter. В плоть до получения отрицательной разницы Coun2-Coun1
p51x
Подтверждения про квант времени я не нашёл, не наблюдалось. Если параметр и влиял, то только в NT3 или NT4 или Win95.
Win98 Win2000 я проверял — там этот параметр не влияет там влияют другие параметры описанные в предыдущем сообщении.
А как вообще лучше использовать таймер в игре? Вот, например, есть 2D игра, персонаж идет с одной скоростью, бежит с другой, картинки анимации движения меняются с третьей,падает перс с четвертой скоростью и т.д. Есть еще анимация, не связанная с персонажем.
Для всего этого:
1. делать отдельные таймеры?
2. Один таймер и менять у него интервал?
3. Один таймер с постоянным интервалом, но для каждой анимации вычислять прошедшее время.
По первому пункту получается много таймеров и возникает путаница когда какой включать, какой выключать.
По второму пункту я пробовал, но в конец запутался со сменой интервалов. И для разных объектов со своей анимацией это не подходит.
Попробовал третий пункт и столкнулся с проблемой данной темы. Т.е. допустим у меня картинки анимации перса меняются каждые 80 мс. Таймер у меня с интервалом 20 мс. И есть счетчик последней смены картинки. Каждый такт таймера я увеличиваю счетчик. Но сначала я увеличивал его на интервал (20), потому что думал, что таймер срабатывает каждые 20 мс (а на самом деле 30 мс), т.е. на каждом такте я получал погрешность в 10 мс и суммарная задержка сильно выросла. Потом я стал увеличивать счетчик на рассчитанное время такта (QueryPerformanceCounter), но в этом случае картинки сменяются не равномерно.
Как вообще это делается?
Источник
Не работает таймер
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Не работает таймер в потоке
unit VkThread; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics.
Как работает Таймер?
Помогите пожалуйста,на форму кинул две кнопки баттон,на клик баттон1 создал: .
Не сохраняются данные и не работает таймер
Доброго времени суток, сейчас пишу одну программу, вообщем необходимо сохранить в файл данные, у.
Почему не работает таймер в практически бесконечном цикле?
Вобщем код такой. procedure TForm1.Timer1Stop(Sender: TObject); begin //procedure .
при назначении функции второй параметр (_In_ UINT_PTR nIDEvent) игнорируется, т.е. в функции не различить от какого таймера произошел вызов (если таймеров несколько)
Добавлено через 1 минуту
То есть поставить знак @ в CreateTimer а передавать функцию?
Как работает таймер относительно основного потока приложения?
код программы исполняется по стандарту сверху-вниз, так? А как в этот процесс вписывается таймер.
При открытии программы таймер работает с прежнего места
Здравствуйте. Подскажите пожалуйста, как сделать, чтобы при закрытии программы таймер запоминал то.
Не работает таймер
Привет всем! Скажите пожалуйста, есть таймер в index.php, на денвере она работает точно, т.е.
Не работает таймер
Здравствуйте! Создала психологический тест. В нем должен быть таймер, я его поставила, добавила.
Источник