Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/47: Рейтинг темы: голосов - 47, средняя оценка - 4.68
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128

IdHTTP->Get в потоке и прогрессом

29.08.2012, 17:39. Показов 9164. Ответов 45
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
TIdHTTP *HTTP = new TIdHTTP(NULL);
    if (HTTP) {
        try {
            HTTP->ConnectTimeout = 10000;
            HTTP->ReadTimeout = 10000;
            if (HTTP->Connected()) HTTP->Disconnect();
            html = HTTP->Get("http://checkip.dyndns.com/");
        }
        catch (...) {} //Соединение не установлено
        try {HTTP->Socket->Close();}
        catch (...) {HTTP->Disconnect();}
        delete HTTP;
        HTTP = NULL;
    }
Хочу засунуть его в поток, получаем
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
String html;
 
void __fastcall Th::Execute()
{
    int p1, p2;
    TIdHTTP *HTTP = new TIdHTTP(NULL);
    if (HTTP) {
        try {
            HTTP->ConnectTimeout = 10000;
            HTTP->ReadTimeout = 10000;
            if (HTTP->Connected()) HTTP->Disconnect();
            html = HTTP->Get("http://checkip.dyndns.com/");
        }
        catch (...) {} //Соединение не установлено
        try {HTTP->Socket->Close();}
        catch (...) {HTTP->Disconnect();}
        delete HTTP;
        HTTP = NULL;
    }
    p1 = html.Pos("Address:")+9;
    p2 = html.Pos("</body>");
    html = html.SubString(p1,p2-p1);
    Synchronize(&UpdateMemo);
}
 
void __fastcall Th::UpdateMemo()
{
        Form1->Memo1->Lines->Add("WAN IP: " + html);
}
Вроде работает, но как сделать прогресс? На форме это делалось добавлением TIdHTTP на форму и там в Event'ах выставлялись функции... А вот в потоке как их создать я не догнал... ?
Пример Event'ов для IdHTTP из формы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//---------------------------------------------------------------------------
void __fastcall TForm1::work(TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCount)
{
    Form1->Memo1->Lines->Add(AWorkCount);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::workBegin(TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCountMax)
{
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::workEnd(TObject *ASender, TWorkMode AWorkMode)
{
 
}
//---------------------------------------------------------------------------
//В Unit1.h:
void __fastcall work(TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCount);
void __fastcall workBegin(TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCountMax);
void __fastcall workEnd(TObject *ASender, TWorkMode AWorkMode);


И пару вопросов по потокам:
  • String html пришлось сделать глобальной - есть ли другие варианты для передачи в Synchronize()?
  • Если я из потока вызываю функцию, которая написана в Unit1 (т.е. она не относится к потоку) - она же будет потом работать в этом потоке? (главное убрать из функции контакт с формой?)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.08.2012, 17:39
Ответы с готовыми решениями:

Как ускорить чтение с прогрессом в потоке
Есть класс Reader который читает содержимое файлов в DataTable. Но есть проблема. Если мы Дергаем делегат прогресса из цикла чтения то это...

Отправка вайла в потоке idhttp
Ребят, загрузчик файлов на сервер через idhttp + idmultipartformdata работает на ура. Но есть проблема - нужно сделать загрузку в...

idhttp в потоке получает пустой txt файл
Доброго времени суток. Пишу обновлялку для программы. Собственно, если код вставлен в FormCreate - все работает. Если же вставить в...

45
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.08.2012, 19:36
Если в потоке прогресс лучше не лепить... будет тормозить... тут нужно подумать как зделать чтоб не подтормаживало...

А вообще у тебя избыточный код....

Цитата Сообщение от ExeiLj Посмотреть сообщение
String html пришлось сделать глобальной - есть ли другие варианты для передачи в Synchronize()?
Сделать её членом класса потока.

Цитата Сообщение от ExeiLj Посмотреть сообщение
Если я из потока вызываю функцию, которая написана в Unit1 (т.е. она не относится к потоку) - она же будет потом работать в этом потоке? (главное убрать из функции контакт с формой?)
Ф-ция будет работать в том потоке, который её вызывает...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.08.2012, 19:37
Если в потоке прогресс лучше не лепить... будет тормозить... тут нужно подумать как зделать чтоб не подтормаживало...

А вообще у тебя избыточный код....

Цитата Сообщение от ExeiLj Посмотреть сообщение
String html пришлось сделать глобальной - есть ли другие варианты для передачи в Synchronize()?
Сделать её членом класса потока.

Цитата Сообщение от ExeiLj Посмотреть сообщение
Если я из потока вызываю функцию, которая написана в Unit1 (т.е. она не относится к потоку) - она же будет потом работать в этом потоке? (главное убрать из функции контакт с формой?)
Ф-ция будет работать в том потоке, который её вызывает...
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
29.08.2012, 20:51  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Если в потоке прогресс лучше не лепить... будет тормозить... тут нужно подумать как зделать чтоб не подтормаживало...
Как это сделать, даже если не в потоке, но без формы и компонентов на ней? Это бы понять, а потом и к потоку приспосабливать...

Цитата Сообщение от Avazart Посмотреть сообщение
А вообще у тебя избыточный код....
В смысле?

Цитата Сообщение от Avazart Посмотреть сообщение
Сделать её членом класса потока.
Можно пример


Цитата Сообщение от Avazart Посмотреть сообщение
Ф-ция будет работать в том потоке, который её вызывает...
Но если функция трогает элементы на форме, то форма зависнет... я так понимаю.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.08.2012, 20:55
Катаю пример....

Пока только это (без потоков) https://www.cyberforum.ru/blog... og608.html
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
29.08.2012, 21:21  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Катаю пример....

Пока только это (без потоков) https://www.cyberforum.ru/blog... og608.html
Это я читал, там все через компоненты на форме, мне надо чистый код...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.08.2012, 21:51
Это я читал, там все через компоненты на форме, мне надо чистый код...
Вообще то там есть примеры создания диначмически компонентов....
В смысле?
Не зачем закрывать сокет, так как компонент все равно уничтожается... должен уничтожатся ( а у тебя там и этого нет...)

Пример с потоком без прогресса...
Вложения
Тип файла: rar IdHTTP And TThread.rar (768.4 Кб, 67 просмотров)
1
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
30.08.2012, 02:08  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Вообще то там есть примеры создания диначмически компонентов....
У меня и так динамический компонент
C++
1
TIdHTTP *HTTP = new TIdHTTP(NULL);
Иначе бы у меня не работало, ведь на форме у меня компонентов нет.

Цитата Сообщение от Avazart Посмотреть сообщение
Не зачем закрывать сокет, так как компонент все равно уничтожается... должен уничтожатся ( а у тебя там и этого нет...)
Чего нет?
Вот компонент уничтожается
C++
1
2
delete HTTP;
HTTP = NULL;
Использовать std::auto_ptr не вижу смысла, т.к. я и сам могу уничтожить, когда это надо!

А насчет сокета... ты уверен, что не стоит его закрывать перед уничтожением? А то поток тоже можно уничтожить, но при этом память он нифига не очистит. Кроме случая, если закроется сам. Поэтому на всякий и стоит закрывать, думаю. К тому же этот код я считал с этого форума.

Цитата Сообщение от Avazart Посмотреть сообщение
Пример с потоком без прогресса...
Ну это у меня и так работает...да...суть как раз таки в прогрессе...
но спасибо за участие
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2012, 02:14
Иначе бы у меня не работало, ведь на форме у меня компонентов нет.
Работало бы... но лучше создавать динамически...

А насчет сокета... ты уверен, что не стоит его закрывать перед уничтожением? А то поток тоже можно уничтожить, но при этом память он нифига не очистит. Кроме случая, если закроется сам. Поэтому на всякий и стоит закрывать, думаю. К тому же этот код я считал с этого форума.
Конечно деструктор должен все сделать, а вот попыка закрыть сокет может наделать делов ...
так как сама может бросить исключение...как и сам дисконект...
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
30.08.2012, 08:13
лучше сделать потоковый класс сделать независимым от Form1, иначе если и дальше поступать так с классами, то головной боли будет не избежать и проект будет заброшен.
проверено на себе.
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
30.08.2012, 19:18  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Работало бы... но лучше создавать динамически...
Неа, если убрать "не динамическое" создание
C++
1
TIdHTTP *HTTP = new TIdHTTP(NULL);
и не размещать компоненты на форме - ничего работать не будет.

Выдержка из статьи, по вашей ссылке
C++
1
2
// Динамическое создание
TIdHTTP* IdHTTP2= new TIdHTTP(NULL) ;



Цитата Сообщение от Avazart Посмотреть сообщение
Конечно деструктор должен все сделать, а вот попыка закрыть сокет может наделать делов ...
так как сама может бросить исключение...как и сам дисконект...
Ну не знаю, весьма спорный вопрос.

Цитата Сообщение от kzru_hunter Посмотреть сообщение
лучше сделать потоковый класс сделать независимым от Form1, иначе если и дальше поступать так с классами, то головной боли будет не избежать и проект будет заброшен.
проверено на себе.
В смысле не зависимым от Form1? вы про Synchronize(), который связан с формой? т.е. без него обойтись советуете?
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
30.08.2012, 21:32
Цитата Сообщение от ExeiLj Посмотреть сообщение
В смысле не зависимым от Form1? вы про Synchronize(), который связан с формой? т.е. без него обойтись советуете?
нет, просто убрать связь с Form1, т.е. сделать потоковый класс полностью независимым.
приложил проект
Вложения
Тип файла: rar HttpThread.rar (16.9 Кб, 57 просмотров)
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2012, 22:20
и не размещать компоненты на форме - ничего работать не будет.
Если без прогресса, то будет, IdHTTP можно вызывать из потока если, он на форме- он ведь не визуальный.
Но вот просто тогда нужно будет учитывать "предыдущие состояния компонента" и сбрасывать его: т.е например закрывать сокеты, дисконектить. (это кстати описано у меня в блоге и ссылка на тему там есть)

Ну не знаю, весьма спорный вопрос.
Да че тут спорного компонент при удалении должен сам за собой почистить...

Вчера запарился я чет с прогрессом.
(Добавил прогресс)
Вложения
Тип файла: rar IdHTTP And TThread And TProgressBar.rar (387.9 Кб, 47 просмотров)
1
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
31.08.2012, 14:27  [ТС]
Цитата Сообщение от kzru_hunter Посмотреть сообщение
нет, просто убрать связь с Form1, т.е. сделать потоковый класс полностью независимым.
Вы просто нажали File -> New -> Thread Object ? Я так и делал

Цитата Сообщение от kzru_hunter Посмотреть сообщение
приложил проект
Весьма замудренный прогресс у вас)) но логика ясна

Цитата Сообщение от Avazart Посмотреть сообщение
и не размещать компоненты на форме - ничего работать не будет.
IdHTTP можно вызывать из потока если, он на форме
Я немного запутался

Цитата Сообщение от Avazart Посмотреть сообщение
Но вот просто тогда нужно будет учитывать "предыдущие состояния компонента" и сбрасывать его: т.е например закрывать сокеты, дисконектить. (это кстати описано у меня в блоге и ссылка на тему там есть)
Да, это относится, если поместить компонент IdHTTP1 путем переноса на форму. Если же этот компонент не выносить на форму, и не создать new TIdHTTP в коде, то вы нигде и никак не сможете вызвать IdHTTP1->Get("");

Цитата Сообщение от Avazart Посмотреть сообщение
Да че тут спорного компонент при удалении должен сам за собой почистить...
Ладно, уговорили
Понял свою ошибку, код брал отсюда: Как проверить наличие соединения с Интернетом\Сетью
Дак вот там просто нет динамического создания компонента, а используется IdHTTP1, у которого нет деструктора, потому и прописано закрытие...

Цитата Сообщение от Avazart Посмотреть сообщение
Вчера запарился я чет с прогрессом.
(Добавил прогресс)
Благодарю, мсье оказалось все не так уж и сложно

PS: У вас в блоге "Компонент IdHTTP" в главе "9. Получение страниц в сжатом виде." указан пример с гуглом - вам следует добавить в код-пример
C++
1
IdHTTP2->HandleRedirects= true;
, потому что гугл работает через перенаправление, и без его разрешения будет постоянно вышибать ошибку.
2
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2012, 15:53
Это то что касалось закрытие сокета

Цитата Сообщение от Avazart Посмотреть сообщение
Пробую этот код. Как бы работает.
Но вот в чем проблема компонент создается не динамически и если отключаю интернет - нажимаю кнопку, выбивает что интернета нет(или 11001 или 10054) потом я подключаю интернет и при повторной проверке- опять выбивает туже ошибку говоря что интернета нет ( хотя он есть ).
Я так понял компонет не выходит из "состояния ошибки".
Можно ли как то "сбросить его" или есть только единственный вариант- создавать динамически?
И если создавать динамически как обеспечить гарантированое удаление компонента учитывая то что есть еще обработка исключений?
Цитата Сообщение от MikeSoft Посмотреть сообщение
Цитата Сообщение от Avazart
Я так понял компонент не выходит из "состояния ошибки".
Вы должны его выводить, сам он практически ничего не сделает.
При получении ReadTimeout соединение останется открытым, поэтому его нужно закрыть.
Если компонент создается "перетаскиванием на форму" то деструктор будет вызываться только после уничтожения формы(автоматически)

Добавлено через 12 минут
Цитата Сообщение от ExeiLj Посмотреть сообщение
потому что гугл работает через перенаправление, и без его разрешения будет постоянно вышибать ошибку.
Уже исправил,спасибо...

Добавлено через 3 минуты
оказалось все не так уж и сложно
Я просто предположил что загрузка может длится дольше чем без прогресса, так как постоянно нужно "стучатся" и "просить доступ" к этому прогрессбару из потока загрузки
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
31.08.2012, 18:06  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Я просто предположил что загрузка может длится дольше чем без прогресса, так как постоянно нужно "стучатся" и "просить доступ" к этому прогрессбару из потока загрузки
По сути, я буду использовать только Begin и End, Work же использовать не буду, за счет чего загрузка не будет постоянно просить доступ к прогресс бару. Проще повесить простую цикличную анимацию загрузки, чем делать полноценный прогресс бар, потому что AWorkCountMax частенько выдает 0 и отображать реальный прогресс не получится.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2012, 18:07
В ноль может выпадать из-за редерикта... и Begin и End могут выполнятся более чем один раз.
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
31.08.2012, 18:52  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
В ноль может выпадать из-за редерикта...
Нет, у меня выключен редирект, пробовал разные сайты.

Цитата Сообщение от Avazart Посмотреть сообщение
Begin и End могут выполнятся более чем один раз.
Если б они выполнялись несколько раз, то каждый раз в Memo добавлялась бы строка...а она добавляется по разу.

И еще вопрос по потокам: известно, что поток должен закончить работу сам, чтобы освободить память. Если его прервать, то память освобождена не будет.
Так вот если во время выполнения потока (например, той же загрузки страницы) я закрою программу, то он завершится некорректно? надо прописать какие-то условия, чтобы при закрытии поток прекращал работу?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2012, 18:56
Так вот если во время выполнения потока (например, той же загрузки страницы) я закрою программу
Ну если вы задали соответвоющее свойство то будет, если нет то его нужно его затерминатить и delete, где-то в FormDestroy() или FormClose()
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
31.08.2012, 19:10  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Ну если вы задали соответвоющее свойство то будет, если нет то его нужно его затерминатить и delete, где-то в FormDestroy() или FormClose()
Т.е. если я сделаю по вашему примеру в Потоке FreeOnTerminate = true; мне больше ни о чем беспокоится не стоит? конечно, кроме момента повторного нажатия кнопки, тут уже надо будет сделать, что-то типа
C++
1
If (Thread) Thread->Terminate();
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.08.2012, 19:10
Помогаю со студенческими работами здесь

Отправка картинки IdHTTP POST в потоке TMemoryStream
Получаю я картинку(капча) в поток(TMemoryStream) посредством запроса. Потом мне нужно эту картинку отправить на сервис, вот тут я...

IdHTTP и IdHTTP сервер: как отправить сообщение от сервера к клиенту?
Всем привет, отправляю файл по частям с клиента на сервер, и хочу получать обратное сообщение, что текущая часть файла дошла успешно....

Скачивание файла с прогрессом
Привет. Есть на HTTP сервере файл &gt; 10 MB надо его скачать. URL url = new URL(...); File file = new File(getApplicationDir(),...

Очистка папки с прогрессом
Очистка папки с прогрессом. Здравствуйте! Необходимо сделать так что-бы при очистке какой-либо папки был прогресс выполнения данной...

Скачивание файла с прогрессом
Ставлю на загрузку файл. Хочу чтобы отображался прогресс скачивания. Программа тупо зависает до момента окончания скачивания private...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru