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

Вниз

Почему у потока вызывается 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.044 c
1-90836
lipskiy
2002-03-15 15:23
2002.03.28
TWebBrowser: как программно подсунуть ему ссылку на выполнение кода в самой программе?


1-90849
baston
2002-03-16 19:12
2002.03.28
Как создать подобную вкладку


1-90880
Olivka
2002-03-16 19:27
2002.03.28
мышь и прокрутка StringGrid-a


1-90895
Света
2002-03-18 10:06
2002.03.28
Выход из цикла


3-90804
lightix
2002-03-04 15:38
2002.03.28
Подскажите БД + Quick Report





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский