Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.12.04;
Скачать: CL | DM;

Вниз

TTimer-в чем ошибка?   Найти похожие ветки 

 
Диана   (2003-11-25 14:34) [0]

Добрый день!
Я написала у себя в программе

Timer.Enabled:=true;
Timer.OnTimer:=calculate;

Когда программа доходит до второй строчки,то вылетает и пишет
Not Enough timers available.
В чем же дело?
Спасибо!


 
clickmaker ©   (2003-11-25 14:38) [1]

Вообще-то лучше наоборот, сначала обработчик прицепить, а потом уже включать
И как calculate выглядит?


 
Goffman ©   (2003-11-25 14:41) [2]

А что написано в calculate?


 
Диана   (2003-11-25 14:44) [3]

>>clickmaker ©
Я сейчас написала Timer.OnTimer:=calculate,где Timer.Enabled=false
,но результат тот же


 
Юрий Зотов ©   (2003-11-25 14:45) [4]

Похоже на какой-то цикл или рекурсию, создающую огромную кучу таймеров.


 
Диана   (2003-11-25 14:47) [5]

>>Юрий Зотов ©
Нет ,там нет циклов вообще


 
clickmaker ©   (2003-11-25 14:47) [6]


> Диана (25.11.03 14:44) [3]

Значит "пряники кончились". Скорей всего - Юрий Зотов © (25.11.03 14:45) [4]


 
Диана   (2003-11-25 14:52) [7]

Я еще делаю присвоение
Timer.Enabled:=true;
до него Timer.Enabled было true, а оно становится после присвоения
false!!!


 
Palladin ©   (2003-11-25 14:55) [8]

или таймер создается по таймеру


 
Юрий Зотов ©   (2003-11-25 15:15) [9]

> Диана

Мы будем дальше играть в угадайку, или Вы все-таки приведете код обработчика OnTimer? А заодно и код создания таймера, если он создается динамически.

Здесь телепатов нет, верите?


 
Диана   (2003-11-25 19:04) [10]

Я решила опубликовать часть программы,где есть ошибка.Посмотрите,
пожалуйста!

TProgram=class(TThread)
end;

//Эта процедура заполняет список объектами из файла
//Раньше она не была поточной и все работало нормально

procedure TProgram.Execute;
var Stream: TFileStream;
t:TConi;
cont:TContact;
i,j,x,x1,y1,x2,y2,y,qx,qy:integer;
alien1,alien2,old,value:integer;
position:int64;
parent:TScrollbox;
begin
Form1.ScrollBox2.Hide;
Stream := TFileStream.Create(filename, fmOpenRead ) ;
alien1:=0;
alien2:=0;
old:=Programe.List.Count;
//Stream.Size;
while Stream.Position<Stream.Size do
begin
try
position:=Stream.Position;
Programe.List.Add(Stream.ReadComponent(nil)as TListElem);
except
Stream.Position:=position;
break;
end;
TListElem(Programe.List.Last).Elem:=Stream.ReadComponent(nil) as TElement;
if alien1=0 then parent:=Form1.Scrollbox1
else
begin
dec(alien1);
parent:=Form1.Scrollbox2;
end;
if alien2<>0 then dec(alien2);
TListElem(Programe.List.Last).Elem.Parent:=parent;
value:=1;
if TListElem(Programe.List.Last).Elem is TLine then
if TLine(TListElem(Programe.List.Last).Elem).Height>
TLine(TListElem(Programe.List.Last).Elem).Width then
value:=2
else
value:=3;
if not(TListElem(Programe.List.Last).Elem is TCombi)and
(TListElem(Programe.List.Last).Elem.Parent=Form1.Scrollbox1) then
setterritory(TListElem(Programe.List[Programe.List.Count-1]).elem.Left-(TListElem(Programe.List[Programe.List.Count-1]). elem.Left mod 5)-5,
TListElem(Programe.List[Programe.List.Count-1]).elem.Top-(TListElem(Programe.List[Programe.List.Count-1]).elem.Top mod 5),
(TListElem(Programe.List[Programe.List.Count-1]).elem.Left+TListElem(Programe.List[Programe.List.Count-1]).elem.Width+5) ,
(TListElem(Programe.List[Programe.List.Count-1]).elem.Top+TListElem(Programe.List[Programe.List.Count-1]).elem.Height),v alue);
if (TListElem(Programe.List.Last).Elem is TCombi) and (alien1=0) then
begin
alien1:=TCombi(TListElem(Programe.List.Last).Elem).count-1;
continue;
end;
if (TListElem(Programe.List.Last).Elem is TCombi) and (alien1<>0) and (alien2=0)then
begin
alien2:=TCombi(TListElem(Programe.List.Last).Elem).count-1;
continue;
end;
with TConDisTrig(TListElem(Programe.List.Last).Elem) do
begin
(TListElem(Programe.List.Last).Elem as TConDisTrig).incontacts:=TList.Create;
(TListElem(Programe.List.Last).Elem as TConDisTrig).outcontacts:=TList.Create;
for j:=0 to incount-1 do
begin
incontacts.Add(Stream.ReadComponent(nil)as TContact);
TContact(incontacts[j]).Parent:=parent;
TContact(incontacts[j]).vlabel:=Stream.ReadComponent(nil)as TLabel;
TContact(incontacts[j]).vlabel.Parent:=parent;
TContact(incontacts[j]).Owner:=integer(TListElem(Programe.List.Last).Elem);
end;
outcontacts.Add(Stream.ReadComponent(nil)as TContact);
TContact(outcontacts[0]).vlabel:=Stream.ReadComponent(nil)as TLabel;
TContact(outcontacts[0]).Parent:=parent;
TContact(outcontacts[0]).vlabel.Parent:=parent;
TContact(outcontacts[0]).Receivers:=TList.Create;
TContact(outcontacts[0]).Owner:=integer(TListElem(Programe.List.Last).Elem);
if(TListElem(Programe.List.Last).Elem is TConDis)and
(TContact(TConDis(TListElem(Programe.List.Last).Elem).outcontacts[0]).Left=
Programe.inbox.Left+Programe.inbox.Width-3)and(alien2=0)then
begin
TContact(TConDis(TListElem(Programe.List.Last).Elem).incontacts[0]).Parent:=Form1.Scrollbox1;
TContact(TConDis(TListElem(Programe.List.Last).Elem).incontacts[0]).vlabel.Parent:=Form1.Scrollbox1;
end;
if(TListElem(Programe.List.Last).Elem is TConDis)and
(TContact(TConDis(TListElem(Programe.List.Last).Elem).incontacts[0]).Left=
Programe.outbox.Left)and(alien2=0)then
begin
TContact(TConDis(TListElem(Programe.List.Last).Elem).outcontacts[0]).Parent:=Form1.Scrollbox1;
TContact(TConDis(TListElem(Programe.List.Last).Elem).outcontacts[0]).vlabel.Parent:=Form1.Scrollbox1;
end;
if TListElem(Programe.List.Last).Elem is TLine then
begin
TContact(incontacts[0]).Owner:=integer(TConDis(TListElem(Programe.List[TContact(outcontacts[0]).elemindex]).Elem).outcon tacts[0]);
TContact(outcontacts[0]).Owner:=integer(TConDis(TListElem(Programe.List[TContact(outcontacts[0]).elemindex]).Elem).outco ntacts[0]);
end;
Timer:=Stream.ReadComponent(nil)as TTimer;
if TListElem(Programe.List.Last).Elem is TConDis then
TConDis(TListElem(Programe.List.Last).Elem).Timer.OnTimer:=
TConDis(TListElem(Programe.List.Last).Elem).calculate;
//Если тут написать
//Timer.Enabled:=true;
//то ОШИБКИ НЕ БУДЕТ
end;
end;
while Stream.Position<Stream.Size do
begin
for j:=old to Programe.List.Count-1 do
if TListElem(Programe.List[j]).Elem is TConDis then
with TContact(TConDis(TListElem(Programe.List[j]).Elem).outcontacts[0]) do
for i:=0 to (TListElem(Programe.List[j]).Elem as TConDis).rescount-1 do
begin
cont:=Stream.ReadComponent(nil)as TContact;
cont.elemindex:=cont.elemindex+old;
TContact(TConDis(TListElem(Programe.List[j]).Elem).outcontacts[0]).Receivers.Add(
TContact(TConDis(TListElem(Programe.List[cont.elemindex]).Elem).incontacts[cont.contindex]));
end;
end;
Stream.Destroy;
Form1.ScrollBox2.Show;
end;

//А ошибка,о которой я говорила,возникает при обращении к этой
//процедуре,которая выполняется после предыдущей

procedure TProgram.calculate;
var i:integer;
begin
for i:=0 to self.List.Count-1 do
if (TListElem(self.List[i]).Elem is TConDis)
and not TConDis(TListElem(self.List[i]).Elem).Timer.Enabled
then
begin
TConDis(TListElem(self.List[i]).Elem).Timer.Enabled:=true;
//Тут и происходит ошибка,хотя это присвоение работает
//внутри Execute нормально!
end;
end;

И дело,как вы понимаете,здесь не в Calculate


 
Диана   (2003-11-25 19:07) [11]

Удалено модератором


 
Юрий Зотов ©   (2003-11-25 19:29) [12]

> Диана

Сразу бросается в глаза, что таймер создается в дополнительном потоке. Но ведь класс TTimer работает через окно, а оконная модель VCL однопоточна. Полагаю, из-за этого и возникает какой-то конфликт.

Сейчас уже надо бежать, а завтра постараюсь посмотреть более подробно.


 
Stilgar ©   (2003-11-25 20:01) [13]

Timer.Enabled:=true;
Timer.OnTimer:=Имя_Объекта.calculate;
Если не ошибаюсь, объект называется Program, тогда
Timer.Enabled:=true;
Timer.OnTimer:=Program.calculate;
Объясняю: OnTimer: TNotifyIvent
TNotifyIvent = procedure(Sender: TObject) of object


 
Диана   (2003-11-25 20:06) [14]

->Stilgar
Суть Вашего совета мне не совсем понятна,либо Вы советуете то,что
я напечатала выше.


 
Stilgar ©   (2003-11-25 20:07) [15]

Вдогонку.
Юрий Зотов прав, все операции с VCL надо производить в процедуре, вызываемой методом Synchronize:
Synchronize(процедура);


 
Диана   (2003-11-25 20:23) [16]

Stilgar

Что Вы имеете в виду под процедурой?


 
default ©   (2003-11-25 20:32) [17]

Диана (25.11.03 20:23) [16]
type TThreadMethod = procedure of object;
procedure Synchronize(Method: TThreadMethod);


 
Диана   (2003-11-25 20:38) [18]

->default ©
Вас я тоже не очень понимаю,можно подробнее?


 
default ©   (2003-11-25 20:45) [19]

Диана (25.11.03 20:38) [18]
это ответ на Ваш вопрос "Что Вы имеете в виду под процедурой?"


 
Stilgar ©   (2003-11-25 20:46) [20]

Прошу прощения, я думал что параметр просто процедура. Оказывается это метод без параметров:
TThreadMethod = procedure of object;
Что же по поводу Program.calculate;, то я ошибся, в методе класса ТProgram работает и так.
Насчет подробнее можна прочитать в автоматически созданых коментариях в юните с потоком, там все лаконично и ясно.


 
Диана   (2003-11-25 20:54) [21]

->Stilgar ©
Эта Ваша процедура TThreadMethod что именно должна содержать?Мне
ею нужно что-то заменить или что-то дополнить?


 
default ©   (2003-11-25 20:59) [22]

Диана (25.11.03 20:54) [21]
в этом методе содержится код потока(содержать должен то, что Вам нужно и без чего Вы жить не можете)


 
Stilgar ©   (2003-11-25 21:13) [23]

Не заменить и не дополнить. Создать. С любым именем и без параметров. И там использовать компоненты на форме. В часности
Timer.OnTimer:=calculate;
Timer.Enabled:=true;
Но если Вы создадите таймер в рантайм непосредственно в потоке эта проблема исчезнет (AFAIK)
2 default
Код потока содержится в Execute, а тут содержится код взаимодействия данного потоки и основного потока приложения.


 
Диана   (2003-11-25 21:15) [24]

->default ©
Вы имеете в виду ,что нужно его вызывать из Execute или что-то другое;частью чего он должен являться:потока или чего-то другого?


 
default ©   (2003-11-25 21:25) [25]

Stilgar © (25.11.03 21:13) [23]
да, думал об одном написал другое)))
Диана (25.11.03 21:15) [24]
"что нужно его вызывать из Execute"
да
procedure TYourThread.Execute;
begin
...
Synchronize(Метод_взаимодействующий_с_основным_потоком);
...
end;



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

Текущий архив: 2003.12.04;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.007 c
6-11659
Cosmic
2003-10-08 18:55
2003.12.04
Хотелось бы примерчик HTTP-сервера...


8-11615
Малой
2003-08-06 14:51
2003.12.04
как из буфура сохранить jpeg?


3-11588
rtooo
2003-11-13 21:57
2003.12.04
какими базами для этого лучше всего пользоваться


1-11613
AMogil
2003-11-25 09:44
2003.12.04
Проблема с фокусом ввода


6-11642
BlackSun
2003-10-05 18:21
2003.12.04
Отправка письма с маленьких exe-шником