-
Доброго времени суток всем! Столкнулся со следующей проблемой,- создаю объект класса TThread (вернее, от класса-наследника :-), запускаю (в его execute всего 1 вызов функции, в которой в свою очередь идут вызовы других функций, создание объектов разных классов и т.д., в основном работа связана с обработкой большого количества файлов, ну и поиском их по папкам). Так вот почему то случайным образом возникает ошибка, после того как я делаю вызов suspend и terminate, приложение подвисает... Ощущение, что это дедлок какой-то. Прошу совета, как это побороть?))) Да, пробовал в таймере с интервалом 1 Мс поставить Application.ProcessMessages,- не помогло... + В другом таймере (с интервалом 1Мс), когда мне нужно завершить поток, вставить if (not th.suspended) then th.suspend;
if (not th.terminated) then th.terminate; Не помогло.
-
> if (not th.suspended) then th.suspend; > if (not th.terminated) then th.terminate; > Не помогло. >
А обязано было помочь ?
-
> случайным образом возникает ошибка
В алгоритмике и программировании любая "случайность" есть следствие закономерности)
-
Ну по идее поток так должен завершиться) В 90% случаях он и завершается... Сергей, может подскажете, что может помочь?))
-
> AndreiDeJavu (17.03.08 14:30)
> делаю вызов suspend и terminate, приложение подвисает... > Ощущение, что это дедлок какой-то.
Это называется suspend. Сделай еще resume - и будет те щастье.
-- Regards, LVT.
-
> по идее поток так должен завершиться
По чьей идее ?
> что может помочь?
Помочь может внимательное изучение всего того что происходит при вызовах этих (и многих других) методов поточного класса.
Suspend "вгоняет" поток в вечную спячку. А Terminate всего лишь устанавливает поле FTerminated = True
Т.е. ты сказал потоку "Засни, зараза !" и после этого требуешь от него каких-то контролируемых им действий)
-
Leonid, после resume поток возобновляет работу... а мне нужно гарантированно его завершить.
Сергей, а есть метод или способ работы с этим классом, при котором поток был бы гарантированно "убит", вне зависимости от того, что в нем выполняется и как? То-есть, в любой момент времени я мог бы по клику баттона его обрубить.))
-
> AndreiDeJavu (17.03.08 14:57) [6]
Есть. Но не метод, а стандартная WinAPI-функция TerminateThread(). По сути ее применение оправдано лишь в аварийных случаях, т.е. в случаях, которые программист по той или иной объективной причине не может предвидеть. Сомневаюсь, что тотт самый "аварийный случай" и есть твой случай.
-
А корректно ли искользовать TerminateThread() при работе с объектом, наследуемым от TThread?
-
Ответственность за последствия использования этой ф-ции целиком и полностью лежит на тебе.
Но еще раз заостряю твое внимание - применение этой ф-ции оправдано только в критических ситуациях. Твои же жалобы на якобы "подвисание" чего-то там без детального изучения и четкого понимания причин этого подвисания не являются поводом для применения этой функции.
-
> AndreiDeJavu (17.03.08 15:13) [8]
> А корректно ли искользовать TerminateThread() при работе > с объектом, наследуемым от TThread?
Пиши корректные функции потока, которые реагируют на Terminate, тогда и не будет нужды в TerminateThread.
А Suspend/Resume - это, во-ще, отладочные функции, в обычной жизни их не пользуют.
-- Regards, LVT.
-
Сергей, Leonid, Интересно, а как сделать так, чтобы код функций, которые выполняются в потоке, не жил своей жизнью, а реагировал на Terminate?=)) У меня там проводятся довольно емкие вычисления...ProcessMessages не помогает.
Может Syncronize?))
-
> AndreiDeJavu (17.03.08 15:36) [11]
> как сделать так, чтобы код функций, которые выполняются > в потоке, не жил своей жизнью, а реагировал на Terminate? >
Встречный вопрос - как сделать так, чтобы, к примеру, как можно быстрей узнать о наличии почтовой корреспонденции в своем почтовом ящике ?
-
> Встречный вопрос - как сделать так, чтобы, к примеру, как > можно быстрей узнать о наличии почтовой корреспонденции > в своем почтовом ящике ?
Наверное, жать F5 при веб интерфейсе, или держать программу клиент в свернутой в трее)). Это к тому, что нужно как то опрашивать код, выполняемый в потоке?))) Я понимаю, что это необходимо, но не знаю, как это сделать, как определить, какая именно строчка спустя минуту после запуска потока выполняется, и как сказать потоку,- стоп, умри.))
-
> Наверное, жать F5 при веб интерфейсе, или держать программу > клиент в свернутой в трее
Я вообще-то об обычном почт.ящике, висящем у тебя в подъезде или на калитке) Чем чаще ты к нему бегаешь, тем быстрее получишь почту, если ты ее вообще ждешь.
Не бегаешь - вообще ничего не получишь, за тебя никто туда бегать не будет)
> как сказать потоку,- стоп, умри
Прямая аналогия с почтовым ящиком:
- Со стороны потока-отправителя процедура помещения в ящик корреспонденции выглядит как вызов метода Terminate
- Со стороны потока-получателя проверка ящика на получение ожидаемой корреспонденции выглядит как булево св-во Terminated.
-
Сергей, procedure th.execute; begin if not terminated then Proceeding( strDirName ); end;
Но у меня в Proceeding еще очень много вызовов других функций, те в свою очередь вызывают еще и еще... Как они в свою очередь узнают о том, что им пора б закругляться?)
-
> Как они в свою очередь узнают о том, что им пора б закругляться?
Так ничто ж не мешает в телах этих функций обращаться к св-ву Terminated)
-
То-есть, если функций штук 300... получается просто жесть...)) Ну ладно, спасибо). Буду дописывать.
-
> если функций штук 300... получается просто жесть
> Буду дописывать.
"Дописывать" надо с умом. Проверка на Terminated имеет смысл лишь в длительных по времени алгоритмах, в первую очередь циклических.
-
> Проверка на Terminated имеет смысл лишь в длительных по > времени алгоритмах, в первую очередь циклических.
Ok)). Так и сделал, вроде все отлично). Спасибо!
|