| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: WinAPI и системное программирование > Запустить процедуру по завершению потока |
| Автор: Bose 7.2.2006, 17:01 |
| Собственно сабж. Есть простой способ это сделать без извратов с Messageами? |
| Автор: _hunter 7.2.2006, 17:06 |
| сам организуй обмен -- держи общий ресурс ( список/очередь ) и пиши в него из потоков. а какой-нит менеджер будет читать... |
| Автор: Bose 7.2.2006, 17:17 |
| Нужно, чтобы форма вызвала процедуру, после того как поток уже полностью отработает... Пока что сделал, чтобы в Поток.ОнТерминэйт включался таймер, а сама процедура запускалась уже из таймера... Просто интересно, может быть есть какое-то более элегантное решение |
| Автор: _hunter 7.2.2006, 17:29 |
| более элегантное решение ( в данной ситуации ) -- послать форме сообщение. |
| Автор: Bose 7.2.2006, 17:52 |
| мне не очень хочется связываться с сообщениями... |
| Автор: _hunter 7.2.2006, 18:29 |
| и чем это нежелание обосновано? |
| Автор: Bose 7.2.2006, 19:08 |
| во-первых жутким страхом новизны во-вторых, поверхностным знанием темы: не хочется попасть в ситуацию, когда сгенерированный мной Message(WM_USER+999 например), уже будет использоваться другим приложением в-третьих: мне кажется, что Messageи стоит использовать в тех случаях, когда без них ну никак не обойтись - например для оповещения других(своих) приложений или форм, до которых средствами Дельфей не добраться.. в-четвертых: imho использование Messageй сродни использованию оператора Goto... будет сложнее ориентироваться в коде и отслеживать ошибки.. в-пятых: в данном конкретном случае, такой вызов надо сделать всего один раз |
| Автор: _hunter 7.2.2006, 19:28 |
| страхи нужно преодолевать а с какой стати кто-то будет слать твоей программе свое сообщение? а тут другими средствами ( не считая синхронизации ) и не доберешся... делегатов в делфи нету. введение потоков так же ( и таким же образом ) усложняет ориентирование. поэтому послать сообщение проще, чем заморачиваться с синхронизацией. |
| Автор: _hunter 7.2.2006, 20:08 | ||||||
могут конечно и гулять, но это уже параноя -- как ты быдеш знать что никто кроме пользователя не нажмет на кнопку, не откроет файл...
почему? есть, конечно, вероятность потери сообщения, но она довольно низкая ( и это опять же параноя ) но если есть серьезные основания для волнения по этим пунктам -- пиши менеджер потоков.
это так, но ты же сам писал "но нельзя её вызывать в OnTerminate." или я что-то пропустил? |
| Автор: Bose 8.2.2006, 10:50 | ||||||||
я не понимаю, как отсылка сообщения может это гарантировать... Предположим я отсылаю сообщение в обработчике OnTerminate.... Его принимает моя форма и вызывает нужную процедуру. Но я не уверен, что система форма не обработает это сообщение до разрушения потока(выхода из OnTerminate) или я заблуждаюсь?.
про событие OnTerminate я писал к тому, что в этом конкретном случае нет никаких заморочек с синхронизацией вариант с OnTerminate у меня не работает. Я и тему создал, чтобы понять как обойти это событие |
| Автор: _hunter 8.2.2006, 11:36 | ||
ты отсылаеш сообщение последней строкой Execute' а потока. это гарантирует что поток не выполняется ( зачем может понадобится гарантия разрушения?.. )
я понял, что я ничего не понял... рассказывай о проблеме ( и задаче ) с самого начала |
| Автор: Bose 8.2.2006, 11:55 |
| _hunter проблема была такая: по окончании действия потока, нужно было вызвать одну процедуру(которая создавала модальную форму, выполняла некоторые длмтельные действия, закрывалась и освобождала форму). Идеальным решением было бы вызвать эту процедуру в событии потока OnTerminate. Но... этот вариант почему-то не работал. Процедура запускалась, форма создавалась, но, действия не выполнялись Точнее после уничтожения, потому что поток работает с БД, и отключается от неё в событии OnTerminate. Процедура, которую мне нужно вызвать, должна работать с этой же БД. Вот и был вопрос как вызвать мою процедуру не из потока, когда поток перестанет существовать. В качестве решение проблемы я сделал следующее: поставил на форму выключенный таймер с интервалом 1000 мс. в событии потока onTerminate этот таймер включается в событии onTimer таймера запускается моя процедура Проблема решена, но решение некрасивое. Зато работает |
| Автор: _hunter 8.2.2006, 12:30 |
| а зачем отключаться в OnTerminate? отключайся в потоке. + лучше бы проблему додавил а не обходы искал... ++ с таймером код стал гораздо чибальнее и понятнее? ;) P.S. отправка сообщения ( в данном случае ) -- идеальный вариант. P.P.S. а что будет если паралельно кто-то запустит тяжелый процесс ( и за секунду твой отключиться не успеет )? |
| Автор: Демо 8.2.2006, 12:31 | ||||||
| Bose OnTerminate - как раз то место, которое нужно использовать для подобной задачи. Так как ты не привел код потока, то могу предположить, что завершающие действия по работе с БД у тебя находятся в деструкторе. Следовательно, в OnTerminate ты пытаешься работать без завершения рабты с базой. OnTerminate вызывавется ДО деструктора Destroy. В твоем случае метод решения может быть простой:
Вызов:
Добавлено @ 12:32 Сорри, процедуру OnComplete надо исключить из методов класса:
PS. Писал прямо здесь, могут быть опечатки. |