| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Завершение потока |
| Автор: ZBugz 6.1.2010, 14:12 | ||
| Всем привет. Первый раз пользую потоки Все работает, потоки - сила. Но вот столкнулся с такой проблемой, поток пошел в execute, все пашет, жму кнопку, делаеться Terminate указанного потока. Удаляю данные из ячейки, и меня в ошибку выкидывает. А выкидывает потому что поток еще не Terminate, а где то TCopyThread.Progress шатаеться... Ну и я тут в ступоре, как сделать так, что бы дождаться его Terminate ? Так пробывал:
Не помогает :( Тока с примером, если можно, а то для меня потоки это темный лес |
| Автор: RA 6.1.2010, 16:11 | ||
Ну если не вешать всяких своих проверок то по пришествию события OnTerminate. А так по сути проблемы не мешало бы код увидеть ... |
| Автор: artsb 6.1.2010, 18:51 |
| ZBugz, вызов метода Terminate не уничтожает поток, а лишь взводит флаг Terminated, который нужно проверять в потоке и если он взведён, завершать его работу. Ну а проверить завершился ли поток можно функцией GetExitCodeThread. В lpExitCode заносится код завершения потока либо STILL_ACTIVE, если поток ещё работает. |
| Автор: Демо 7.1.2010, 23:01 | ||||
| ZBugz, В реализации Delphi есть метод WaitFor для ожидания завершения поточной функции. Использовать можно в случае FreeOnTerminate=False; т.е.
Если нужна периодическая проверка, тогда можно периодически проверять результат функции
|
| Автор: ZBugz 8.1.2010, 13:03 |
| Народ, я ничего не понял вообще Код выложить пока не могу, негде написать пример... |
| Автор: ZBugz 8.1.2010, 13:25 | ||||||
А в проекте так:
И вот где брейк, что то надо делать, что бы ждать когда он завершиться....
Добавлено через 1 минуту и 12 секунд Нажимаею кнопку и передаю
Где idx номер потока котрый грохнуть |
| Автор: artsb 8.1.2010, 14:39 | ||
|
| Автор: ZBugz 8.1.2010, 14:58 | ||||||
Так все удаляю, ща вот точнее как у меняя там:
То что free не срабатывает, это я понял давно, точнее он то срабатывает, а поток в это время гуляет TCopyThread.Progress Мне бы как то это бы отловить бы, что пока он не завершиться, free не делать... |
| Автор: artsb 8.1.2010, 17:08 |
Вы что, пытаетесь уничтожить поток внутри него же? ИМХО у вас вообще организация неправильная. Что вы хотите сделать вообще? Какова цель? |
| Автор: ZBugz 8.1.2010, 19:38 | ||||||
Не обращайте внимания, это я для примера так написал. Я смысл хотел передать, что Terminated в Execute срабатывает, в finally выходит вроде, все делаеться, но на самом деле он не звершен И еще, я не знаю, поможет или нет, но когда только создаю поток, он успешно рубиться в Execute, а все синхронайзы(Progress), т.е. вывода информации, как то сначала запаздуют с отображением, а то ка потом вся инфа идет. И точно так же получаеться что он и выходит их Execute Мне бы какой нить цикл, который ждал бы завершения именно этого потока, а потом уже вываливался в тот же
Добавлено через 1 минуту и 23 секунды
Кстати, а почему это не прокатит ? Поток потоком, а stream - стримом. Они же не пересекаються никаким способом.... ?! |
| Автор: ZBugz 8.1.2010, 21:19 | ||||
Так вот, я делаю все, а оно делаеться, но с опозданием. Т.е. все работает, в 99%, а в оставшемся случае, тупо не успевает уничтажаться. Добавлено @ 21:19
Прям в Execute. Вроде как одно другому не мешает |
| Автор: artsb 8.1.2010, 22:14 | ||
Так и уничтожайте там же. После проверки флага Terminated, уничтожте и выходите из функции. Или Stream в это время ещё нужна? Добавлено через 4 минуты и 21 секунду
задержку при старте можно объяснить синхронизацией ИМХО, а вот по поводу того что у вас в конце там тормозит, я так и не понял толком Ага. |
| Автор: ZBugz 9.1.2010, 09:16 | ||||||
Не, не нужна. Я ее там же и уничтажаю. Выше в код е написанно, что грохаю все.
|
| Автор: artsb 9.1.2010, 10:10 | ||||
эм... не верю Добавлено через 4 минуты и 57 секунд Т.е. вы хотите сказать, что это работает:
, а Stream уже уничтожен? Добавлено через 6 минут и 25 секунд Кстати, у вас в коде проверка Terminated стоит в самом конце. Там от неё толку нет |
| Автор: ZBugz 9.1.2010, 11:29 | ||||||||
Дык вот именно так. Сам в шоке
Ага И я вот тут в ступоре, как это отловить... Ща одна мысля появилась, потестю пока ее.
Всмысле ? |
| Автор: artsb 9.1.2010, 11:56 | ||
| Странно... А что у вас в функции "progress"? Это:
стоит в самом конце функции. Какой толк от этого? Циклов у вас не наблюдается. Хотя может вы не весь код привели... |
| Автор: ZBugz 9.1.2010, 12:13 | ||||||
Там вывод информации, вот он там что то пытаеться вывести того, чего нету уже...
Это не весь код, это в середине, а в начале там всякие переменные присваиваються и т.д. |
| Автор: artsb 9.1.2010, 12:20 |
Так давайте весь |
| Автор: ZBugz 9.1.2010, 12:50 | ||||
Ну все тоже самое
Synchronize(Progress) идет через таймер, что бы ниче при отображении не мигало. Я подозреваю его, хотя что free, что destroy, пофигу, все равно отрабатывает Synchronize(Stop), а в то же время поток еще Synchronize(Progress) Добавлено через 6 минут и 3 секунды Причем щас прошелся еще раз дебагером, выходит Synchronize(Stop), все там делает, а потом как все там прошел, уходит в Synchronize(Progress) Это как ? |
| Автор: artsb 9.1.2010, 13:12 | ||
ИМХО лучше так:
И что-то не видно Stream... |
| Автор: ZBugz 9.1.2010, 13:55 | ||||||
Ну да, чето не заметил
|
| Автор: artsb 9.1.2010, 14:38 |
ZBugz, ты меня запутал |
| Автор: ZBugz 9.1.2010, 14:49 | ||
Дык нету ошибки явной. Смысл вот в чем, все работает, берешь удаляешь данные из ячейки listview, передаю терминэйт, а так как уже после терминэйт все free, то вывод данных в ячейку падает в ошибку.... Их брать то уже негде... Кстати, почитал я, так вот, такое часто, к примеру, при копировании файла. Так вот у меня именно тоже самое что и тут http://forum.vingrad.ru/forum/topic-60076/anchor-entry480375/0.html Тока в этой статье ничерта не понятно как реализовать остановку |
| Автор: ZBugz 9.1.2010, 19:52 |
| Тут пришел мой начальник Далее, кое че подправил, читая статью про потоки, все почти работает. Смысл в том что действительно, делая файловые операции в потоки, это жесть, в плане отловки закрытия файлов, поток потоком, а файловые операции, это лперации... Ими управляет система. |
| Автор: Демо 9.1.2010, 23:35 | ||||
Это не бред, и живёт таймер в потоках весьма хорошо. Бред - эта цитата. Вот Application.ProcessMrssages в потоках - это явный бред, используется лишь с целью исправить ошибки проектирования и реализации, внося в приложение элемент непридсказуемости поведения и увеличивая количество глюков. >Автор Как я выше написал, чтобы дождаться окончания выполнения поточной функции, в Delphi есть метод TThread.WaitFor. Твоя нить при установке флага Terminated должна немедленно закончить работу. Непонятно, в чём у тебя проблема.
А не судьба проверить установку флага Terminated везде, где это может повлиять на работу приложения? |
| Автор: ZBugz 10.1.2010, 13:22 | ||||||||||
Значит таймер может быть рожденный в потоке и жить хорошо ?
А как тогда быть ? Вообще убрать ?
Я не пойму как ее использовать
Так она и вроде как и заканчивает работу.
Я сделал это, в одном месте (проверку в TCopyThread.Progress, все хорошо), но проблема именно в том, что сам windows не успевает закрыть файлы или ему антивирус мешает и т.д. , поэтому получаеться что я пытаюсь открыть еще не закрытый файл... |
| Автор: Демо 10.1.2010, 13:42 | ||||
Вполне;) ни в коем случае не используй эту функцию в дополнительных потоках. Вот смотри: В реализации TThread устанавливаешь FreeOnTerminated := False; В коде, где у тебя нужно дождаться завершения потока:
После выполнения этого кода у тебя гарантированно отработал деструктор потока.
Попробуй код из предыдущего абзаца. Если ошибка останется, значит всё же логическая ошибка где-то в другом месте. |
| Автор: artsb 10.1.2010, 14:12 | ||
Демо, ZBugz хочет сделать эту проверку в самом потоке (в функции Execute), если я правильно понял Ну и это
Будет там не в тему. Если честно, я до сих пор не могу понять что и где работает не так |
| Автор: Демо 10.1.2010, 14:31 | ||
Дык перечитай топик-) Terminate для завершения потока и используется. У автора секретная программа |
| Автор: artsb 10.1.2010, 14:56 |
Эмм... Насколько я понял, топикстартер хочет делать эту проверку именно после проверки флага Terminated. Или до меня опять не дошло |
| Автор: ZBugz 10.1.2010, 16:53 | ||||||||||||||
Тогда пока оставлю
Завтра попробую без не, впринципе мысль была, что впринципе нафиг там не нужно это.
Я нечно пробывал, но у меня ошибки получались. Завтра еще попробую, отпишусь.
Да все хорошо. Я понял почему ошибка, отловил, не страшно. Добавлено @ 16:54
Ага, именно после проверки, послал Terminated и жду пока он 100% убьеться поток. Добавлено через 3 минуты и 54 секунды
Ага |
| Автор: artsb 10.1.2010, 17:02 |
И действительно. Я что-то внимания не обратил. ProcessMessages, насколько мне известно, служит для "насильной" обработки пришедших сообщений, которые не могут обработаться при выполнении ёмкой операции. Это, например, перерисовка формы, перемещение формы и т.п. А вы пытаетесь вызвать её из потока, которому эти сообщения и даром не нужны. |
| Автор: ZBugz 11.1.2010, 10:25 |
| Я почитал, что ProcessMessages надо юзать тогда, когда ты выводишь информацию на контролы, но если пользуешь синхронайз, то он нафиг не нужен вообще. |
| Автор: artsb 11.1.2010, 10:36 | ||
Из справки:
|
| Автор: ZBugz 11.1.2010, 17:23 |
| Короче убрал я ProcessMessages и Timer. Demo помог. Ошибки почти все пропали. С таймером тяжко все таки в моем случае... |
| Автор: ZBugz 8.2.2010, 16:55 |
| Ну короче новая проблема Обрабатываю все в TCopyThread.Destroy А можно ли в TCopyThread.Destroy обрабатывать визульные компоненты ? Т.е. вызывать там всякие удаление ячеек и т.д. без синхронайз ? |
| Автор: artsb 8.2.2010, 16:59 | ||
ИМХО можно, но лучше не нужно. конечно же, нет. |