![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
MrDmitry |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Здравствуйте. Бьюсь над проблемой уже несколько дней и в конце концов решил обратится за помощью к вам.
Написал небольшую dll библиотеку в которой создается Tidhttp. Примерно выглядит так
Таких функций в моей библиотеки несколько, каждая для своих целей. Пока работает IdHTTP1 основная форма зависает. Поэтому было решено использовать потоки. Но проблема в том что по мимо того что до этого я не работал с потоками так тут еще нужно выполнить функции в потоке из библиотеки в теле самой программы. В идеале должно получится. Нажали кнопку на панели появляется надпись "Запрос отправлен, пожалуйста подождите." Если все успешно отправилось то появляется временная надпись "Операция успешна завершена" если ошибка то появляется в той же панели "Ошибка при отправки запроса". По потокам читал интереснейшую статью на этом форуме Многопоточность - как это делается в Дельфи и попытался сделать все сам. Создал скелет модуля thread (file->new->thread object) засунул туда обращение к dll
Дальше попытался это запустить в потоке и вошел в ступор. Уже голова пухнет. Так что буду рад любой помощи Это сообщение отредактировал(а) MrDmitry - 16.12.2011, 16:45 |
||||
|
|||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
-------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
нет. Поэтому и обращаюсь за помощью к вам
|
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
MrDmitry, может стоит учебник по делфи для начала почитать... тип параметров в функции кто будет указывать?
-------------------- There are always someone smarter than you... |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
||||
|
||||
MrDmitry |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
парни. Эту функцию я указал как пример. Ну да забыл указать тип параметров. библиотека работает. вопрос в том как заставит работать созданный обьект Idhttp через потоки чтоб не подвисала программа. Вот для людей которые сразу кидаются, рабочий участок кода из длл(без потока)
|
||||
|
|||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
MrDmitry, зачем указывать изначально неверные примеры?
Вообще наверное стоит сначала попробовать реализовать работу с IdHTTP в потоке без выноса кода в dll... Да и на один явный ляп Akella уже указал. И вообще, ВОПРОС какой стоял? "Использование потока"... Сами же писали: Где код с попыткой обернуть вызов функции из dll в поток? p.s. string'и используются, а sharemem в uses указан, где надо? -------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Да что вы привязались к dll? Я же говорю что библиотека работает.
Давайте поставим вопрос проще. Уйдем от Длл. Как сделать чтоб при работе idhttp программа подвисала, при помощи потока? |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
кто привязался? см. -------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Очень долго не писал ) Но проблему на некоторое время забросил и не решал. Собственно повторю суть вопроса. Нужно вызвать из dll поток. Обработать в нем данные и вернуть в основной модуль программы.
Вот какая dll получилась
Тут собственно вызывается поток.
Тут обрабатывается сам поток
Только не смейтесь. Этот модуль служит для связи основного модуля библиотеки и потока. Долго ломал голову как передать данные из mytype в основную функцию библиотеки, в итоге додумался до такого варианта )
Вот такой вызов dll при первом нажатии кнопки res.balance возвращается пустым. ((( При повторном возвращается то что нужно. Это сообщение отредактировал(а) MrDmitry - 19.1.2012, 16:16 |
||||||||
|
|||||||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Так что у меня не так? Дайте пищу для размышлений а то мыслей уже не осталось
|
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Похоже что нужно использовать SYNCHRONIZE но все мои попытки синхронизации четны. (((((
|
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
Сделай тестовый проект/группу, чтобы можно было сразу ошибку твою "поймать", и приложи аттачем.
Но код у тебя ужасно отформатирован. просто нет слов. Это сообщение отредактировал(а) MetalFan - 21.1.2012, 14:04 -------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Вот
Насчет форматирования. Первоначально оно было, но после того как я уже переписал все 100 раз на форматирование я уже перестал обращать внимания Присоединённый файл ( Кол-во скачиваний: 3 ) ![]() |
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
С исходниками стало еще тяжелее помочь? (
|
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
MrDmitry, хм, ну зря ты считаешь, что все тут только сидят и ждут, как бы кому-нибудь помочь.
Посмотрю на досуге приложеный проект. Добавлено через 13 минут и 17 секунд Мда. ну во первых, при передаче строк в/из библиотеки первым модулем в проектах приложения и библиотеки должен быть упомянут ShareMem. Во-вторых... что-то я про потоки вообще не понял... card_info в библиотеке запускает поток и не дожидаясь окончания его работы выходит, возвращая "пустой" по сути результат... Поток, отработав, записывает результат в ГЛОБАЛЬНУЮ переменную, второй вызов (нажатие кнопки) запускает поток еще раз и по сути возвращает результат работы первого потока. На мой взгляд все написано очень криво с кучей недочетов... но для начала разбирания работы с потоками сойдет. Твори дальше) -------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
а разве у меня в dll ShareMem не указан 1? И почему он должен быть первым? Вить компилятор не ругается не настадии компиляции не в процессе работы уже скомпилированного приложения?
ну и самое главное. А как заставить card_info ожидать завершение потока а патом выходить? |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
MrDmitry, если ты не читаешь, что тебе пишет САМА делфя в комментарии при создании новой библиотеки, то это твои проблемы.
А смысл делать операцию в потоке, если потом безусловно ждать (читай-замораживать вызывающий поток) окончания его выполнения. Это сообщение отредактировал(а) MetalFan - 24.1.2012, 11:37 -------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
C sharemem я понял. В самой dll у меня она на 1 строчке uses а в приложении забыл (( Но вот с потоком вы отвечаете для меня не понятно. Вернее я понял что у меня функция не правильно работает с потоком. Она вызывает поток, заносит данные в глобальную переменную, но не дожидаясь окончания работы завершается. Это я понял еще на 1 странице этой темы, а вы подтверждаете мои догадки. Но смысл этой темы в том что я не знаю как решить эту проблему, ибо моих знаний в работе с потоком и вообще в delphi не достаточно. Я не прошу сделать какую то работу за меня. Или написать какой то код. Мне бы хотелось, если это вас не обременит, чтоб вы более подробно написали что делать? А именно как заставить функцию ждать завершения потока PS Сейчас в голову пришла мысль сделать примерно так
Все срабатывает как надо ) Но наверное такой вариант не эстетичен Это сообщение отредактировал(а) MrDmitry - 24.1.2012, 14:38 |
||||||
|
|||||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
MrDmitry, я просто не понимаю, зачем нужно выполнение кода в отдельном потоке, если не обеспечивается параллельная работа вызывающего потока.
Дождаться окончания работы потока можно с помощью TThread.WaitFor -------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
Ну это всего лишь макет. В будующем будет так. Пользователь запрашивает информацию по выбранной карте. Интернет может быть разный, чтоб вся программа не "подвисала" в момент пока ждет ответа код выполняется в потоке, при этом в label пока не будет получен ответ будет выводится сообщение, "Запрос отправлен, пожалуйста подождите." Все остальные кнопки до получения данных будут блокироваться. В этом же разделе я задавал другой вопрос. Как все выше задуманное осуществить? И мне посоветовали использовать потоки. Вот я их и использую. Возможно не рационально и не правильно, но еще раз повторяюсь, раньше не пользовался потоками. Это мой первый опыт.
PS тот код который я написал скорее всего с изьяном. Веть если будет какой то сбой, например php который мне выдает данные с сервера будет по какой то причине не доступен. то в res.sucess у нас не за несется данных и значит цикл будет бесконечным ( при TThread.WaitFor программа зависает намертво ( Это сообщение отредактировал(а) MrDmitry - 24.1.2012, 18:35 |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
учесть это и тогда не будет WaitFor ждет окончания работы потока (читай - завершения работы Execute). -------------------- There are always someone smarter than you... |
|||
|
||||
MrDmitry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 556 Регистрация: 10.11.2006 Репутация: нет Всего: нет |
И можно последний вопрос? А как бы вы реализовали то что мне нужно было? Не прошу код. На словах )
|
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
MrDmitry,
У тебя задача: узнать из одного потока (в твоем случае - главного), что отработал либо обработал данные второй поток, так? Тут на мой взгляд масса вариантов: 1. При вызове отдать указатель на функцию обратного вызова (callback), которую затем дергать по окончанию обработки данных в потоке. Синхронно или асинхронно с главным потоком. 2. При вызове отдать ссылку (хэндл, либо указатель на VCL обертку) объект синхронизации (Event?), состояние которого будет изменено по окнчанию работы доп.потока и отслеживать это состояние в первом потоке, к примеру, по таймеру. 3. Отправлять сообщение (Send/Post Message) окну в главном потоке по окончанию обработки 4. Подвариант 2го пункта. Создать пайп, отдать его доп.потоку, а затем ждать данные через него в осн.потоке. 5. ...много чего еще можно нафантазировать. -------------------- There are always someone smarter than you... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |