Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Форма зависает из-за idhttp / 24 сообщений из 24, страница 1 из 1
01.04.2015, 17:48
    #38924145
Vitorrio
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Форма зависает из-за idhttp
Из-за частых запросов idhttp форма безбожно тормозит.
Если я функцию из которой происходит вызов засуну в поток idhttp будет параллельно работать с несколькими соединениями?
Если нет, как еще можно решить проблема?
...
Рейтинг: 0 / 0
01.04.2015, 17:52
    #38924147
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Форма зависает из-за idhttp
Насколько помню, Indy и так создаёт отдельный поток для обработки каждого http-запроса.
...
Рейтинг: 0 / 0
01.04.2015, 18:46
    #38924185
Vitorrio
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Форма зависает из-за idhttp
RWolf,

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

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

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

Использовать TIdAntiFreeze?
...
Рейтинг: 0 / 0
18.01.2018, 13:53
    #39586422
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Форма зависает из-за idhttp
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
18.01.2018, 14:43
    #39586461
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Форма зависает из-за idhttp
Квейд, о, благодарю!
Да, по описанию именно оно, положил на форму, как рекомендуют, но чет не помогло...
Буду с ним экспериментировать, думаю это правильное направление ))
Еще раз спасибо!
...
Рейтинг: 0 / 0
18.01.2018, 14:56
    #39586474
krapotkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Форма зависает из-за idhttp
правильное направление выносить долгие операции в отдельный поток, а все остальное - расстановка грабелек по феншую
...
Рейтинг: 0 / 0
18.01.2018, 15:06
    #39586486
s62
s62
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Форма зависает из-за idhttp
Devillio,

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

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

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

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

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

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

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

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

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

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


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