Форум: "Основная";
Текущий архив: 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