Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> таймер в потоке, не работает таймер в классе в потоке 
:(
    Опции темы
yogin
Дата 7.10.2009, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Приветствую.
такая проблема:
главная форма создаёт поток th1, поток th1 создаёт десятки потоков th2, в потоке th2 создаётся представитель класса T1, в этом классе относительно события создаётся класс T2(не во всех потоках th2 сразу, может быть в нескольких одновременно, вообщем зависит от события) и в классе T2 сразу при создании создаётся таймер Timer1, Timer1 создаётся(приравнивается процедура, интервал) и после создания запускается сразу же там же в T2.Create. а затем процедура таймера просто напросто не выполняется... таймер минутный. процедура и сам таймер в private директории класса T2.
в чём же проблема?
PM MAIL   Вверх
CodeMonkey
Дата 7.10.2009, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



В том, что TTimer - оболочка над SetTimer/WM_TIMER и не будет работать в потоке без дополнительных телодвижений?

Зачем вообще нужен в потоке таймер?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
yogin
Дата 7.10.2009, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата

Зачем вообще нужен в потоке таймер?

Имееш ввиду что его можно чем-то заменить? или вообще зачем нужен?
нужен для того, чтобы переменная класса T2 дискриминировалась каждую секунду.
PM MAIL   Вверх
CodeMonkey
Дата 7.10.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(yogin @  7.10.2009,  13:25 Найти цитируемый пост)
нужен для того, чтобы переменная класса T2 дискриминировалась каждую секунду.

Зачем? Не проще считать нужное значение, когда нужно?

// Декремент на 5 каждую секунду
T1 := {начальное значение T} - {Округлить до секунд}({сейчас}-{начальное время}) * 5;
// Инкремент на 1 каждую секунду
T2 := {начальное значение T} + {Округлить до секунд}({сейчас}-{начальное время}) * 1;


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
yogin
Дата 7.10.2009, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата

Не проще считать нужное значение, когда нужно?


А что будет вызывать-то этот подсчёт?
внешнего фактора вызова-то не будет, для этого и нужен таймер.
PM MAIL   Вверх
CodeMonkey
Дата 7.10.2009, 18:08 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(yogin @  7.10.2009,  17:49 Найти цитируемый пост)
А что будет вызывать-то этот подсчёт?

То место, где вы используете переменную.

Вы сказали: "надо, чтобы переменная класса T2 дискриминировалась каждую секунду". 
На самом деле, вам нужно не это. Потому что сама по себе переменная, которая как-то там меняется никому не интересна.
На самом деле, у вас где-то есть код, который работает с этой переменной. Так вот вам надо, чтобы на 5-й секунде значение переменной было 128, на 6-й - 127, а на 7-й - 126 (это я по вашим словам говорю, как я понял).

Я вам и говорю: а зачем вам менять переменную, если её значение можно узнать однозначно в какой хотите момент времени, если вы знаете начальный момент времени? Просто отнимите от неё число прошедших секунд, вот и всё.

Когда ваш код читает значение переменной - просто используйте этот пересчёт.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
yogin
Дата 7.10.2009, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Да, тут получается маленькое недопонимание алгоритма действий.
Он таков:
предположительный таймер вычитает переменную и когда переменная в процедуре таймера вычтется и станет = 0, тогда вызывается определённый метод класса из этойже процедуры таймера.
а затем переменная опять приравнивается 45-и и таймер работает дальше.
работа с переменной происходит каждую секунду в обработчике таймера и нигде более.
поэтому ничем больше не вызвать метод, даже относительно слежения за системным временем, потому что просто не будет никаких вызовов, ведь цикла нигде нет.
PM MAIL   Вверх
bems
Дата 7.10.2009, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Ну тогда это то же самое что 
Код

while True do
 begin
 Sleep(45000);
 Obj.Method;
 end;

Еще наверное нужно предусмотреть выход из потока при завершении приложения, поэтому простой Sleep нужно заменить на какой-то твой евент.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
yogin
Дата 7.10.2009, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата

Ну тогда это то же самое что 

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

необходим какой-то вариант неприхотливого таймера, который работал бы в нитях помимо главной...

Это сообщение отредактировал(а) yogin - 7.10.2009, 20:39
PM MAIL   Вверх
bems
Дата 7.10.2009, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



еще вариант - таймер, вызывающийся в потоке управляемом системой. Тыц

Добавлено через 1 минуту и 53 секунды
Вот аналог работающий и в более старых системах.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
yogin
Дата 8.10.2009, 07:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата

еще вариант - таймер, вызывающийся в потоке управляемом системой.

выглядят функции аппетитно, надо пробовать, скоро отпишусь
PM MAIL   Вверх
CodeMonkey
Дата 8.10.2009, 09:00 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(yogin @  7.10.2009,  20:29 Найти цитируемый пост)
нет, нельзя останавливать весь поток, у него помимо этого необходимого таймера ещё много дел.

Хех, святая простота, а как по-вашему, может ли один поток заниматься ДВУМЯ делами сразу? Правильный ответ: в каждый момент времени один поток может делать что-то одно. Либо он делает "много дел", либо он выполняет "обработчик таймера".

Вот занят у вас поток делами. Наступило время сделать что-то ещё ("обработчик таймера"). КАК вы заставите поток прервать работу и выполнить обработчик? Никак.

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

Либо же вам нужно сделать поток так, чтобы поток время от времени проверял свой статус - ровно так же, как сделан главный поток: главный поток постоянно крутится в цикле, выбирая из очереди сообщения (читай: задачи) и запуская их обработчики (читай: работу). Собственно, TTimer так и работает: он просто в эту очередь в нужный момент вставляет сообщения. Понятно, что если поток слишком долго обрабатывает сообщения (работает над задачами), то и реагировать на таймер он будет с задержкой. Если же поток сделан без цикла, так что он постоянно не выбирает сообщения/задачи, то нельзя в нём и использовать какой-бы то ни было "таймер". Просто потому, что поток физически не может делать два дела сразу.

Вот примерный набросок (работа бьётся на кусочки, которые выполняются в DoSomeWork):

Код
while not Terminated do
begin
  DoSomeWork;   
  if {настало время} then
    DoOnTimer;
end;


Только если вы будете использовать два потока, не забудьте про синхронизацию.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
yogin
  Дата 8.10.2009, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата

Хех, святая простота, а как по-вашему, может ли один поток заниматься ДВУМЯ делами сразу? Правильный ответ: в каждый момент времени один поток может делать что-то одно.

Да, конечно, и поэтому мы спокойно можем его усыплять на 45 секунд.
(не нужно предвзятых фраз, ведь вы всё равно не имеете представления о собеседнике)
стоило лишь немножко подумать и было бы ясно что поток, а точнее подкласс класса потока нужен мне не для реализации какого-то таймера на 45 секунд усыпляющего весь родительский поток!
в крайнем случае можно было посоветовать реализацию потока как таймера изначально, тоже самое только sleep(5) к примеру(что вы и зедлали в последнем посте).
но это тоже не подходит. У меня любое действие в родительском потоке и в подклассах осуществляется внешним вызовом, а сам поток разрушается тоже только по приказу. конечно в нём цикл, но я не собираюсь каверкать этот цикл под мои таймерные нужды.

вообщем я считаю что будет легче сделать из подкласса новый поток уже с функциями таймера типа:
Код

while TRUE do
begin
  dec(i);
  if i <= 0 then 
  begin
    i := 9000;
    OnProcess;
  end;
  Sleep(5);
end;
Terminate;

но функции создания потокового таймера я тоже рассмотрю.

Это сообщение отредактировал(а) yogin - 8.10.2009, 16:07
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0890 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.