Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему у потока вызывается Terminate? [D6, Win2k]


Страницы:   1 2

Aleksandr ©   (2002-03-15 14:03:00) 

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

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

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


kull   (2002-03-16 03:51:00) [1]

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


Aleksandr   (2002-03-15 19:34:00) [2]

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


digitman   (2002-03-15 18:31:00) [3]

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

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

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

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


digitman   (2002-03-15 18:24:00) [4]

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

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


Aleksandr   (2002-03-15 18:24:00) [5]

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

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

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


digitman   (2002-03-15 18:20:00) [6]

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


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

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


Aleksandr   (2002-03-15 18:08:00) [8]

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


digitman   (2002-03-15 17:12:00) [9]

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

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


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

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


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

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. Пройдите по стеку вызовов и найдете причину.


digitman   (2002-03-15 16:36:00) [12]

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


Aleksandr   (2002-03-15 16:17:00) [13]

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


digitman   (2002-03-15 15:55:00) [14]

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


Aleksandr   (2002-03-15 15:51:00) [15]

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


USAtyj   (2002-03-15 15:41:00) [16]

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


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

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


digitman   (2002-03-15 15:15:00) [18]

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

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


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


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


Aleksandr   (2002-03-15 15:01:00) [19]

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


Coalycat   (2002-03-15 14:56:00) [20]

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

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

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

const
TerminateMyThread : Boolean=false;


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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо