Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.12.04;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.004 c
14-11702
OpenGL
2003-11-13 10:48
2003.12.04
Panov


4-11745
menart
2003-10-07 08:32
2003.12.04
shut down для win2000, winnt, winXP


6-11684
Witaliy
2003-10-05 13:24
2003.12.04
Глюк Sleep в TThread


6-11694
Vilux
2003-10-10 14:25
2003.12.04
Работа с сокетами


6-11674
Иг
2003-10-03 17:23
2003.12.04
Ошибка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский