|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
28.11.2011, 13:44 | #11 |
Старожил
Регистрация: 17.11.2010
Сообщений: 18,922
|
Можно сделать и так, как предложено в предыдущем посте, добавив в Destroy передачу сообщения окну для сигнала о том, что поток завершен. При получении этого сообщения окно новый поток будет создавать, возможно сделав небольшую паузу.
Можно и оставить так как есть, пересмотрев кое-что 1. inherited в Execute не понятно для чего (уже говорилось) 2. Если извне сделать Terminated:=True, то все объекты созданные в Execute могут быть и не уничтожены, поскольку уничтожение внутри цикла, куда прога может и не войти, плюс Exit-ы есть в цикле до уничтожения. Если извне не предусмотрена установка Terminated в True, то нафиг все эти проверки внутри Execute этого свойства? Создание и удаление объектов конечно лучше перенести в Create и Destroy 3. У вас синхронный способ создания потоков и для создания его по-новой окно должно дождаться завершения предыдущего экземпляра. А ваше Stop похоже вызывается из потока через fOnTimeout, прикольно. Используйте метод WaitFor в окне для ожидания завершения потока и только после его выполнения уничтожайте поток. Инициализировать процедуру ожидания завершения потока и его уничтожения можно, например, передав сообщение из потока в окно перед самым выходом из Execute.
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Последний раз редактировалось Аватар; 28.11.2011 в 13:47. |
28.11.2011, 15:27 | #12 |
Форумчанин
Регистрация: 16.12.2009
Сообщений: 902
|
Это ты пинг делаешь для Контры как я понял)? У меня есть для контры кое что написано под WinSock сразу можно многопоточность создать, есть опрос мастер серверов, есть прога для управления rcon командами для удаленной консоли, если хочешь могу поделиться, может кое что полезного найдешь и там все на потоках построено
|
28.11.2011, 16:00 | #13 |
Форумчанин
Регистрация: 18.10.2010
Сообщений: 419
|
И(и)звиняйте, всю тему не читал, но у меня была задача, подобная вашей:
нужно выполнять какое-то действие, но не дольше какого-то времени, а по истечении этого времени - прервать действие. Я(я) запускаю поток, который выполняет это действие. Т(т)аймер со стороны по истечении времени просто прерывает этот поток. П(п)рерывает с помощью TerminateThread. Э(э)то жуткая функция, которой все боя(ца)ТСЯ, и применение которой, как я слышал, в корне неправильно, но поток убивает на раз, без всяких тупых вопросов. П(п)росто почитайте возможные опасности, связанные с ней, и решите, надо ли оно вам. Л(л)ично я использую и доволен =) О(о)дна из опасностей, которых все боя(ца)ТСЯ - это неосвобождение памяти после убиения потока. М(м)ол, если убить поток просто так, то он не освобождает объекты, которые создавал. Н(н)о лично я, например не представляю как надо написать программу, чтобы поток там что-то создавал... Я(я) все что надо создаю просто так, а поток уже потом с этим работает... Из правил раздела : 6. У нас принято писать грамотно, нормальным русским языком, с использованием знаков препинания и заглавных букв в начале предложений. "Каша" или "удафф" будут тут же закрыты с выдачей штрафа. Так что, если у вас проблемы с этим, проверяйте свои сообщения на орфографию в Ворде или браузере... Модераторы это дело подправят, а вы получите штраф... Последний раз редактировалось mihali4; 29.11.2011 в 19:19. |
28.11.2011, 17:36 | #14 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
Прочитал все посты, посмотрел код... Скажу вот что: Автор темы, вам следует начать решать проблему не в коде, а в самой концепции. Итак, по порядку:
1. Таймер проверяет, существует ли поток и при необходимости пересоздает поток... Зачем? Убирайте таймер, и перепишите код потока так, чтобы он создавался при старте вашей программы и занимался пропинговкой нужного сервиса на протяжении всей работы программы. Если коннект оборвался или UDP-сообщение не доставлено, то не нужно уничтожать поток! Организуйте цикл Execute так, чтобы в цикле происходил реконнект и пропинговка возобновлялась. 2. Раз в секунду? В цикле потока код: Код:
Код:
4. TPingThread.SetProc может не выполнять код в finally после вызова Exit, если опять-таки, версия Delphi, кажется, ниже 2009. Т.е. Exit не кидает в finally. Если так, то обезопасьте дополнительной оберткой try..except весь код данного метода и замените Exit на Abort. А лучше строки кода по освобождению объектов вынести в деструктор. 5. Грубая ошибка в вашем коде: Код:
Код:
Отдельно для xrob Вам, уважаемый, лучше не писать такие изречения, дабы не позориться. Без обид. Набирайтесь опыта, книги читайте и блоги листайте. WinApi вещь отличная, только ей нужно уметь пользоваться.
"ковыряю изнутри" (с)
Последний раз редактировалось 3D Hunter; 28.11.2011 в 18:19. |
28.11.2011, 19:49 | #15 |
Старожил
Регистрация: 30.12.2009
Сообщений: 11,426
|
3D Hunter, таймер выкинул. Написал конструктор и деструктор.
Только не понял как реализовать reconnect при обрыве связи. Делее понял проблему. в fOnTimeOut у меня выставлен обработчик такого вида: Код:
Код:
Как этого избежать? |
28.11.2011, 19:56 | #16 |
Старожил
Регистрация: 17.11.2010
Сообщений: 18,922
|
OnPingTimeout и не нужен. Сообщение отправляйте перед выходом из Execute, а в обработчике сообщения WaitFor, Free и создание нового потока
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
|
28.11.2011, 20:49 | #17 |
Форумчанин
Регистрация: 16.12.2009
Сообщений: 902
|
Сделай дополнительный класс который будет проверять уничтожение потока, потом через него заново запускай создавая новый поток. Этот же класс и позволит создавать многопоточность отслеживая все потоки.
Один раз создаешь класс по работе с потоком потом он сам будет создавать и уничтожать поток в свой TList он в этот лист вернее в память грузит параметры потоков, с помощью его можешь узнать количество запущенных или узнать уничтожен ли поток по его индексу в листе или идентификатору по спец номеру который задашь потоку. Просмотри ниже прогу, разберешься. Я благодаря ВОВАНУ разобрался с потоками, видел его примеры на них и научился контролировать потоки. Или поищи примеры от ВОВАНА особенно по написанию Mail агента, у него там много чего интересного. http://zalil.ru/32152725 прога для КС опрашивает мастер сервер из списка и выдает сервера в этом сервере. Там в FunctConnect.pas и реализованны все функции потоков по сети, просмотри код и разберешся как приструнить поток) при запуске проги нажми в ней кнопку Загрузить список и ты увидешь в ListView всю инфу о серверах КС которые зарегистрированны на мастер сервере. много чего полезного там есть. Последний раз редактировалось Aliens_wolfs; 28.11.2011 в 21:23. |
28.11.2011, 20:58 | #18 | |
Старожил
Регистрация: 30.12.2009
Сообщений: 11,426
|
эмм,
Цитата:
А про обработчик WaitFor впервые слышу... Можно просвятить? |
|
28.11.2011, 21:25 | #19 |
Старожил
Регистрация: 17.11.2010
Сообщений: 18,922
|
Ну во-первых вроде и нет упоминания, что у вас окна нет, которому можно сообщение передать, во вторых обработчика WaitFor нет, а имелся ввиду обработчик сообщения, в котором выполняеься WaitFor, Free и создание нового потока. Все равно у вас есть поток, из которого запускается пингующий поток. Ставьте сразу после запуска пингующего потока ожидание его завершения, тогда никаких сообщений не нужно
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Последний раз редактировалось Аватар; 28.11.2011 в 21:39. |
29.11.2011, 05:15 | #20 |
Сумрачная тень
Форумчанин
Регистрация: 05.03.2009
Сообщений: 689
|
Вы правильно сказали: объект не может уничтожить сам себя непосредственно, т.к. в этом случае он делает это из своего метода. А после выполнения строчки FreeAndNill() идет возврат в точку вызова для продолжения исполнения линейного кода и... упс! А там-то уже ничего по этому адресу и нет!
Создавать поток только для ожидания завершения другого крайне нерационально. Лучше уж тогда определить событие OnTerminate вашего проблемного потока, и в нем написать код для запуска новой копии потока. Тогда вам не нужно будет заботиться о самопроверке "уничтожен ли я?", а старый поток будет корректно освобождаться в своем деструкторе. Кроме того, получается, что он же и будет контролировать сам себя, говоря лишь в OnTerminate главному потоку приложения создать новую копию себя. По коду: 1. Вынесите процедуру Start в событие OnTerminate. В конструкторе потока установить FreeOnTerminate:=true для самоконтроля. 2. В деструкторе должен выполняться код по освобождению объектов: Код:
Код:
Вот почитайте эту отличную статью про многопоточность: http://forum.vingrad.ru/forum/s/a0e9...y480344/0.html
"ковыряю изнутри" (с)
Последний раз редактировалось 3D Hunter; 29.11.2011 в 05:39. |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
при закрытии потока(Tthread) посылать на форму код ответа или сообщение | Человек_Борща | Общие вопросы Delphi | 2 | 14.12.2010 21:19 |
Работа с TThread | pesi | Общие вопросы Delphi | 2 | 09.08.2010 14:12 |
TThread | Vladislav_I | Общие вопросы Delphi | 0 | 30.04.2010 19:47 |
Ошибка при OpenDialog.Execute | ymka2 | Общие вопросы Delphi | 10 | 27.11.2009 14:15 |
TThread и GUI | Freezer | Общие вопросы Delphi | 8 | 05.08.2009 11:50 |