powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Форма зависает из-за idhttp
24 сообщений из 24, страница 1 из 1
Форма зависает из-за idhttp
    #38924145
Vitorrio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из-за частых запросов idhttp форма безбожно тормозит.
Если я функцию из которой происходит вызов засуну в поток idhttp будет параллельно работать с несколькими соединениями?
Если нет, как еще можно решить проблема?
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #38924147
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько помню, Indy и так создаёт отдельный поток для обработки каждого http-запроса.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #38924185
Vitorrio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RWolf,

Тогда почему форма зависает? Ожидает получения html кода?
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #38924274
Фотография krapotkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IdHTTP1.Get()
вызов блокирующий, не асинхронный
вынести в поток и не мучиться
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Форма зависает из-за idhttp
    #39586328
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проблема та же самая, чтобы не создавать новую тему:

IdHTTP вызывается в отдельном потоке.
Это функция, получающая цены с биржи
Код: pascal
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.
30.
31.
32.
33.
34.
35.
36.
37.
function Yobit_api_public(AURL: String; var IsExcepted: Boolean): String;
var
  Http_req: TIdHTTP;
  AParam: TStringList;
begin
  try
    Http_req := TIdHTTP.Create(nil);
    Http_req.ReadTimeout := 7000;
    Http_req.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
    AParam := TStringList.Create;
    Http_req.AllowCookies := True;

    try
//      DataInfo.ID := 1; DataInfo.IDCommand := umcUpdateDebugMemo;
//      DataInfo.InfoString := 'Yobit_api_public(AURL: String; var IsExcepted: Boolean): String;';
//      SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo));
      Result := Http_req.post(AURL, AParam);
//      DataInfo.ID := 1; DataInfo.IDCommand := umcUpdateDebugMemo;
//      DataInfo.InfoString := '';
//      SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo));
    except
      on pe: EIdHTTPProtocolException do
      begin
        IsExcepted := True;
        Result := ' -> api error : ' + TimeToStr(Time) + ' ' + pe.Message;
      end;
      on e: Exception do
      begin
        IsExcepted := True;
        Result := ' -> api error : ' + TimeToStr(Time) + ' ' + e.Message;
      end;
    end;
  finally
    FreeAndNil(AParam);
    http_req.Free;
  end;
end;


Эта функция вызывается из потока.
С помощью кода, который закомментирован, определил, что именно в этот момент (Result := Http_req.post(AURL, AParam);) иногда происходит "тормоз" основной формы. Проверял так: хватал форму за заголовок и крутил мышкой. Все работает как надо, но иногда (именно что не всегда) в момент idhttp.post форма подвисает как при выполнении длительной операции в основном потоке (и Memo рисует текст "виновной" за подвисание процедуры).
Экспериментами выявил, что если отключить Касперского - глюк становится реже. И еще, в те моменты, когда форма подвисает, обычно возвращается api error : Read timed out.
Как-то можно сделать чтобы все таки основная форма не тормозилась?

это код потока
Код: pascal
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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
procedure TThreadUpdaterCurrentCoinsPrice.Execute;
var IsErr: Boolean; S, T: String;
  tr: TStringList;
  DataInfo: TUpdateMessage;
  i: Integer;
begin
  try
    tr := TStringList.Create;
    tr.Text := ListCoinsPriceUpdate;
    T := '';
    for i := 0 to tr.Count-1 do T := T + ProcUnit.IfThen(LowerCase(tr[i])=LowerCase(BasePair), '', ProcUnit.IfThen(T<>'', '-', '') + LowerCase(tr[i]) + '_'+LowerCase(BasePair));
    if T='' then Exit;

    DataInfo.ID := IDTrader; DataInfo.InfoString := ''; DataInfo.Proc := '';
//    DataInfo.IDCommand := umcBeginUpdateBalance;
//    SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo));
    case IDTrader of
      1: //YOBIT.NET API
        begin
          IsErr := False;
          S := BotYobitUnit.Yobit_api_public('https://yobit.io/api/3/ticker/'+T+'-'+LowerCase(BasePair)+'_usd', IsErr);

          if IsErr then
          begin
            tr.Clear;
            tr.Add(S);
            ProcUnit.WriteEventToTable(IDTrader, 0, 1, tr);
            DataInfo.IDCommand := umcUpdateEvents;
            SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo));

            DataInfo.IDCommand := umcUpdateBalance;
            SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo)); //UpdateMDIBeginEventTimer
            Exit;
          end else
          begin
            S := ProcUnit.ConvertAnswerToINIText(S);
            if not BotYobitUnit.Yobit_is_success(S, T) then
            begin
              tr.Clear;
              tr.Add(T);
              ProcUnit.WriteEventToTable(IDTrader, 1, 2, tr);
              DataInfo.IDCommand := umcUpdateEvents;
              SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo));
              Exit;
            end else
            begin
              DataInfo.InfoString := BotYobitUnit.Yobit_Convert_CoinPrices(S);
//              SendMessage(Application.MainFormHandle, WM_USER + 201, 0, IntPtr(@DataInfo)); //UpdateMemoText
              DataInfo.IDCommand := umcWriteINICoinPrices;
              SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo)); //UpdateMDIWriteINIFunds
              DataInfo.IDCommand := umcUpdateBalance;
              SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo)); //UpdateMDIBeginEventTimer
            end;
          end;

        end;
    end;

  finally
    FreeAndNil(tr);
  end;
end;

...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586336
Сюзанна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Devillio,
SendMessage ожидает ответа
PostMessage не ждет, а продолжает работу
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586380
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сюзанна, это да.
В самой функции SendMessage я ставил когда искал проблемное место (мемо в момент подвисания рисует виновника).
В коде потока SendMessage отрабатывает за миллисикунды, там преобразование json в ini и просто запись в базу.
Форма подвисает именно в момент IdHTTP.Post, но не всегда (повторяюсь), это 146% точно, вот только почему.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586398
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Devillio,

скорее всего проблема в главном потоке в обработке сообщения WM_USER + 100
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586412
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DevillioКак-то можно сделать чтобы все таки основная форма не тормозилась?

Использовать TIdAntiFreeze?
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586422
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius, ну поверьте, ну нет же ((

Для поиска проблемы, я обрамил все процедуры:
в начале процедуры ставил вывод в Memo ее название, в конце - Memo очищается.
Я вертел на мышке главную форму, и в основном все выполнялось плавно (все таблички на форме обновляли данные, а в мемо мимолетно проскакивали названия процедур), но иногда только одно название подвисало на нексолько секунд, в тот же момент висла и форма.
Т.о. было найдено, что глючит именно функция, которая запрашивает текст с сайта. И когда это происходит, в базу пишется "api error: read timed out".

Таким же методом я выяснил на какой строчке глючит, именно IdHttp.Post:
// Когда ремарка снята, перед выполнением Post форма рисует в Memo название
// DataInfo.ID := 1; DataInfo.IDCommand := umcUpdateDebugMemo;
// DataInfo.InfoString := 'Yobit_api_public(AURL: String; var IsExcepted: Boolean): String;';
// SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo));
Result := Http_req.post(AURL, AParam);
// DataInfo.ID := 1; DataInfo.IDCommand := umcUpdateDebugMemo;
// DataInfo.InfoString := '';
// SendMessage(Application.MainFormHandle, WM_USER + 100, 0, IntPtr(@DataInfo));

При отключенном антивирусе заметно улучшается (глюки становятся реже, но не пропадают совсем.
Уменьшение/увеличение параметра Timeout влияет на количество секунд тормоза. Пробовал поставить Timeout :=20000 - так форма и зависает, на порядка 20 секунд.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586461
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Квейд, о, благодарю!
Да, по описанию именно оно, положил на форму, как рекомендуют, но чет не помогло...
Буду с ним экспериментировать, думаю это правильное направление ))
Еще раз спасибо!
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586474
Фотография krapotkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
правильное направление выносить долгие операции в отдельный поток, а все остальное - расстановка грабелек по феншую
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586486
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Devillio,

главный поток может подвисать из-за ожидания дополнительного, если потоки как-то связаны - например второй ждет выполнения SendMessage, когда действия по обработке сообщения выполняются в главном потоке. Или что-то аналогичное. В принципе может быть вариант, когда доп. поток тормозит всю систему, но это вряд ли ваш вариант. Если потоки не связаны, то ожидание дополнительным потоком ответа на запрос по интернету не должно влиять на работу основного потока.
Так что по-моему стоит искать взаимосвязи потоков (в приведенном коде это вызовы SendMessage). Вы кстати не привели код из основного потока, который обрабатывает SendMessage, не показали, как создаете поток.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586498
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрите, возможно Вам подойдет

http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1355
Выделяете часть кода в отдельный поток, основной подождет выполнения задачи в этом потоке.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586509
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Потоки создаю и убираю правильно.
Тормозит именно из-за IdHttp и других причин нет. Пишу же, прежде чем задать вопрос, протестировал всё - абсолютно каждую процедуру - место нашел правильно.
Подобных тем на просторах нашел несколько, именно из потоков IdHTTP у людей глючит, именно что основная форма тормозит, но их решения мне не помогли.
А помогло уменьшение параметра ReadTimeout. Сменил с 7000 на 2000 - зависания стали не более полусекунды, в принципе, для задачи приемлемо.
Не решение, но пойдет.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586533
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
зато теперь чаще будут возникать ошибки таймаута? )
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586544
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Devillio...
Тормозит именно из-за IdHttp и других причин нет. Пишу же, прежде чем задать вопрос, протестировал всё - абсолютно каждую процедуру - место нашел правильно.
Подобных тем на просторах нашел несколько, именно из потоков IdHTTP у людей глючит, именно что основная форма тормозит, но их решения мне не помогли.
...
Да, "кто-то в интернете написал". Ну да, есть такие вопросы. Вот, например: https://forum.antichat.ru/threads/delphi-potok-tormozit-formu.332817/
где начинается:
в то время когда поток посылает POST запросы, форма виснет, как это решить?
в каждом потоке IDhttp свой...
а заканчивается:
Все разобрался, тупанул я жестко, поток запускал не как поток а процедуру в нем(и это делалось через форму ) :D))
Вот так и у тебя скорее всего где-то ошибка, которую ты пока не увидел.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586756
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62,

нам в очередной раз рассказывают сказки про тяжелое детство, вместо того, что бы разобраться.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586791
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Devillio,

Не может из-за работы с TidHttp зависать главный поток. Совет - увеличь таймаут, в момент подвисания запаузи программу, пройдись по потокам и посмотри какой на чем остановился, особенно интересно на чем висит главный поток.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586799
Фотография krapotkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну или хотя бы кусок кода на ревью, как это главный поток зависает...
есть вариант для зависания ГП,
если мы создаем 1000 потоков, так вот пока они создаются и стартуют, он действительно висит...
остальное все точно надуманное
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586903
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZeliusDevillio,

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

это слишком сложно. Отлаживать надо, смотреть что там творится.
Гораздо проще в мемо названия функций выводить.
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586925
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vizit0r, кстати, мне реально сложно. Нажимаю паузу и вижу asm код, дальше F8 - так по asm и перемещается.
Не знаю как определить какой строчке кода этот asm принадлежит.
И не знаю как определять в каком месте сейчас главный поток и все остальные.

А ошибку нашел. Посыпаю голову пеплом, в одном из таймеров было WaitFor, и мой метод проверки, конечно же, неправильный.
ГП заходил в таймер, ждал остановки, и конечно же, эта задержка была в моменты read timeout.
Нормально и даже отлично работает idHTTP из потока :)

Благодарю за помощь!
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586932
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Devillio,

там ничего сложного, я тоже ассемблер не понимаю.
жмешь паузу, открываешь View\Debug windows\Threads, дабл клик по первому потоку в списке, потом открываешь call stack - View\Debug windows\Call Stack, и дабл кликаешь по процедурам... конечно, отладочная информация должна быть включена и дебаг юнитс тоже
...
Рейтинг: 0 / 0
Форма зависает из-за idhttp
    #39586944
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zelius,

как правило, станция останавливается сразу в 'нужном' потоке. достаточно по колл-стэку побегать, даже если в ассемблер забежало.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Форма зависает из-за idhttp
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]