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

Вниз

Почему у потока вызывается Terminate?   Найти похожие ветки 

 
Aleksandr ©   (2002-03-15 14:03) [0]

Есть у меня поток. Существует он в одном экземпляре,
Execute у него обыкновенный:

begin
repeat
if FoundFiles then
DoChanges;
Sleep(500)
until Terminated
end;

Долго я искал, почему сей поток у меня периодически перестает работать, пока не догадался перекрыть ему OnTerminate. И оказалось, что он по непонятным причинам просто делает Terminate.
Почему это происходит и как сделать, чтобы он не Terminate до завершения работы программы?


 
NailS ©   (2002-03-15 14:11) [1]

А стек посмотреть, после того как Terminate поймал?
В функциях FoundFiles и DoChanges исключительных ситуаций не происходит?


 
digitman ©   (2002-03-15 14:17) [2]

что значит - "перекрыть ему OnTerminate" ? Обработчик что ли определить ? Так ведь по-умолчанию он не определен ! Как же он может изменить флаг Terminated, если, к тому же, вызывается уже после завершения метода Execute ?

Флаг Terminated ты "портишь" либо в FoundFiles() либо в DoChanges(). Проверяй досконально все, что делается в этих методах.



 
Aleksandr ©   (2002-03-15 14:34) [3]

Господа, я понимаю, ваши сомнения, но код двух методов слишком велик для его приведения, но весь он стоит в try...except. И при exceptax ведет лог таковых. И весь лог после запуска программы выглядит примерно так (без колонки даты/времени):

15.03.02 10:52:02: Состояние паузы...
15.03.02 10:52:04: Найден 1 файл...
15.03.02 10:52:05: Файл 0002.h00 обработан успешно...
15.03.02 10:52:06: Состояние паузы...
15.03.02 10:52:08: Состояние паузы...
15.03.02 10:52:10: Вызван Terminate!

При этом Terminate не вызывается в программе нигде, кроме ее завершения.


 
digitman ©   (2002-03-15 14:40) [4]

Разве речь идет о вызове Terminate ?
Я ж тебе говорю - где-то в теле этих твоих методов ты "портишь" поле флага FTerminated твоего объекта Thread, причем сам того не подозревая, очевидно ... Проверяй досконально все обращения по записи к полям твоего объекта-потока


 
Coalycat ©   (2002-03-15 14:56) [5]

Если потоков несколько, то удобно сделать так:

repeat
...
...
if ClosePortProcess.WaitFor(50)=wrSignaled
then TerminateMyThread:=true;
until TerminateMyThread;

где ClosePortProcess: TEvent, а TerminateMyThread объявлена как глобальная константа:

const
TerminateMyThread : Boolean=false;


. Один раз Event выставил и все потоки завершатся.


 
Aleksandr ©   (2002-03-15 15:01) [6]

Ладно, поставим вопрос иначе... Какой из стандартных методов Потока может менять флаг FTerminated? Например, если я внутри DoChanges запустил другой поток и сделал его
Changer.Resume;
Changer.WaitFor
может ли он вызвать к прекращению основного потока?
Я сделал легкое извращение: цикл Execute базового потока
begin
repeat
if FoundFiles then
DoChanges;
Sleep(500)
until FGoTerminating
end;
FGoTerminating изменяет свое состояние в верно только при завершении программы... Однако OnTerminate все равно вызывается...
Я извратился еще больше. Просто в цикле оставил методы с пустым телом. Поток все равно прекращает свою работу... Что за нафиг...


 
digitman ©   (2002-03-15 15:15) [7]

вот ты фома неверующий)

при условии, что тобой вызывается стандартный конструктор объекта-потока XXX запусти-ка вот это :


procedere XXX.Execute;
begin
repeat
until Terminated;
end;


цикл будет "крутиться вечно" !!!


 
Юрий Зотов ©   (2002-03-15 15:30) [8]

Если в FoundFiles или DoChanges происходит Exception, который не гасится там же, то это приведет к выходу из Execute. Соответственно, возникнет событие OnTerminate и будет вызыван его обработчик.


 
USAtyj ©   (2002-03-15 15:41) [9]

А память нигде не выделяешь под какие-нибудь переменные?
Я в свое время используя дополнительно длл выделял в самой длл память, вот из-за некорректности выделения, память отведенная под FTerminate переписывалась какими-либо левыми данными. Если там было записано 0 (False), то при записи любого другого числа, получалось True. По-моему в этом может быть причина.


 
Aleksandr ©   (2002-03-15 15:51) [10]

2 Digitman...
Наверное, я сегодня не с той кнопки машину запускал... Мистика... Сделал как у тебя... Останавливается.


 
digitman ©   (2002-03-15 15:55) [11]

во внешних блоках except, в которые заключены тела сомнительных методов, нет финального raise ? если нет, тогда единственный вариант - флаг FTerminated ты "портишь" сам того не ведая при неверных обращениях к памяти по записи


 
Aleksandr ©   (2002-03-15 16:17) [12]

Может быть, и так :(... Только кода дофига, да истчо и не моего, поэтому хрен его, где может raise или запись в память уйти... Есть такие моменты. Тогда вопрос в том, как предохранить поток от остановки обработчиком Except"a? Грубо говоря, как при появлении Exception его мягко убрать, чтобы он не выкидывал фокусов с выходами из методов и изменениями значений пропертей?
Делал я приколку типа
except
on E:Exception do begin
Log(E.Message)
E.Free
end
end;
Пофигу... ошибка все равно уходит в код, вызвавший метод с этим обработчиком...


 
digitman ©   (2002-03-15 16:36) [13]

E.Free ??????!!!!! убери его срочно !
Где, из каких источников ты взял сие ?


 
Юрий Зотов ©   (2002-03-15 16:42) [14]

1. E.Free вызывать не надо - Delphi разруливает такие вещи сама.

2. Напишите Execute так:

try
while not Terminated do
begin
if FoundFiles then DoChanges;
Sleep(500)
end
except
MessageBeep(0)
end;

Затем поставьте BreakPoint на MessageBeep и запустите. Если придете на эту точку, значит, дело именно в Exception. Пройдите по стеку вызовов и найдете причину.


 
Андрей Сенченко ©   (2002-03-15 16:50) [15]

E.Free - очень хороший метод вызвать веселое сообщение о том, что"программа выполнила ..."
Тут то мы все и узнаем.


 
digitman ©   (2002-03-15 17:12) [16]

>Aleksandr
>>"Сделал как у тебя... Останавливается."

Конструктор потока - точно стандартный ?
Тогда следующее предположение : внешний по отношению к объекту-потоку код где-то "гадит" его поля.
Долго так еще будем гадать) ...


 
Aleksandr ©   (2002-03-15 18:08) [17]

Усе... нашел, кто мне гадит...
Смотря в корень, гадит Делфи, позволяя делать вызовы raise (неопределенные), и эти-то неопределенные raise Delphi и не обрабатывает... В итоге блок try..except не помогает корректно продолжить код... Ну а реально остановка была из-за вызова пустого Raise одной из компонент (Indy). Всем спасибо за поссибельную помощь :))


 
DieHard ©   (2002-03-15 18:13) [18]

какие-такие неопределенные?
если в except...end, то они те же самые, что его и вызвали
если вне, то дожен указываться конкретный тип


 
digitman ©   (2002-03-15 18:20) [19]

хммм... что ж это за "пустой Raise" такой ?)
вот загадка так загадка !)


 
Aleksandr ©   (2002-03-15 18:24) [20]

дык в том-то и дело... код в исходнике Indy:

...
if Handler.Active then
...
else Raise;
end;

Переделал ему это дело, объявив новый потомок TException, и пошло как по маслу... Кстати, уже не первый раз такое встречаю, в основном, когда программы с Делфи 3 перерабатываю...


 
digitman ©   (2002-03-15 18:24) [21]

и какой еще Инди там у тебя вдруг появился в АБСОЛЮТНО пустом цикле в Execute при стандартном конструкторе - тоже непонятно)

см.
digitman © (15.03.02 15:15)
и
Aleksandr © (15.03.02 15:51)


 
digitman ©   (2002-03-15 18:31) [22]

Ах, вон оно что !

Так ведь, если это исходнике, на который ты пеняешь, все же выглядит вот так :
...
except
...
if Handler.Active then
...
else Raise;
end;

то это - абсолютно нормальная и корректная ситуация !

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


 
Aleksandr ©   (2002-03-15 19:34) [23]

Нет, это не в Эксепте... А Инди у меня в другом месте есть, не в цикле, и его raise всю программу вышибает...


 
kull   (2002-03-16 03:51) [24]

Ну конечно! Как только ни фига не выходит, так сразу Delphi виноват или Windows глючный.
А может просто на код посмотреть внематочно?
Чудес не бывает!



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

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

Наверх




Память: 0.53 MB
Время: 0.01 c
14-91061
Королев
2002-02-12 17:07
2002.03.28
стоит ли не пить и не курить?


3-90746
AnIg
2002-02-28 18:21
2002.03.28
Кто работал с DBChart ? Что за эффект?


1-90956
som
2002-03-14 14:53
2002.03.28
Zip архивы


14-91074
den_c
2002-02-16 16:50
2002.03.28
нужна документация по написанию сервисов


1-90927
us
2002-03-14 04:15
2002.03.28
Номер версии