Подвисание приложения при выполнении THTTPSend.HTTPMethod

Модератор: Модераторы

Подвисание приложения при выполнении THTTPSend.HTTPMethod

Сообщение ya_vanka » 06.07.2016 14:03:37

Есть приложение, которое в потоке запрашивает файлы с сервера (тайлы Яндекс карт). И все работает, но если в момент вызова HTTPMethod сервер не отдает файл (synsock.Connect отрабатывает с FLastError = 10060, т.е. таймаут операции происходит), то подвисает все приложение.

Есть ли способ убрать подвисание? Пусть поток останавливается, но не все приложение.

Код потока запроса файлов примерно такой:
Код: Выделить всё
procedure TLoadMapTileListThread.Execute;
begin
  HTTP := THTTPSend.Create;
  HTTP.Timeout := 2000;

  while (not Terminated) and (LoadTileIterator.Next(CurrTileXY)) do
  begin
    URL := GetTileURL(CurrTileXY);

    HTTP.Document.Clear;
    HTTP.Headers.Clear;
    LoadTileRes := HTTP.HTTPMethod('GET', URL);

    if (LoadTileRes and (HTTP.ResultCode = 200)) then
    begin
      ...
    end;

    sleep(10);
  end;

  HTTP.Free;
end;
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho

Сообщение Ichthyander » 06.07.2016 16:26:03

Непонятно почему у Вас подвисает все приложение, если запрос делается в отдельном потоке. Только этот поток и должен подвисать, в случае, если сервер не отвечает - Вы же вызываете метод HTTPMethod не внутри процедуры Synchronize

Добавлено спустя 1 минуту 38 секунд:
Re: Подвисание приложения при выполнении THTTPSend.HTTPMethod
Может основной поток у Вас просто-напросто ждет завершения потока TLoadMapTileListThread? Тогда будет подвисать. Нужно смотреть код основного потока
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho

Сообщение ya_vanka » 06.07.2016 16:37:17

Да, похоже так и было.

Тогда возникают другие вопросы:
1. как настроить время таймаута, чтобы не более 2 секунд выполнялся THTTPSend.HTTPMethod?
2. как моментально завершить поток не дожидаясь таймаута в THTTPSend.HTTPMethod?
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho

Сообщение Ichthyander » 07.07.2016 05:05:49

1. Тут все просто: THTTPSend.Timeout - свойство - время таймаута, мс.
2.1. Можно попробовать поиграть с событием THTTPSend.Sock.OnStatus, при наступлении которого проверять свойство Terminated потока, в контексте которого обрабатывается запрос к серверу, т.е.
Код: Выделить всё
procedure TLoadMapTileListThread.HTTPHookSocketStatus(Sender: TObject;
  Reason: THookSocketReason; const Value: String);
begin
  if Terminated then
    FHTTP.Abort;
end; 

Да, экземпляр THTTPSend лучше хранить тогда в виде свойства потока TLoadMapTileListThread, к примеру FHTTP, чтобы можно было обращаться к объекту вне процедуры Execute, в других методах потока TLoadMapTileListThread
Я не уверен, что это работает
2.2. Принудительно прерывать выполнение потока
2.3. В любом случае алгоритм отрабатывает ожидание таймаута ответа с сервера. К примеру, если приложение должно закрыться, основной поток ожидает (WaitFor) завершение потока, которые работает с сервером или просто не дает ему закрыться пока таймаут не будет отработан и поток для работы с сервером сам по себе закроется
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho

Сообщение ya_vanka » 07.07.2016 12:19:04

1. Тут все просто: THTTPSend.Timeout - свойство - время таймаута, мс.


Дело в том, что я ставил свойство HTTP.Timeout := 2000, однако эффекта не было. HTTP.HTTPMethod завершался секунд через 15.


2.1. Можно попробовать поиграть с событием THTTPSend.Sock.OnStatus


Да, это надо попробовать.


2.2. Принудительно прерывать выполнение потока


Вот собственно вопрос как? Как прервать поток не дожидаясь таймаута в HTTP.HTTPMethod? Использовать HTTP.Abort? Он просто выставляет FSock.StopFlag := true. Достаточно ли это для немедленного завершения HTTP.HTTPMethod? Не уверен.
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho

Сообщение Ichthyander » 07.07.2016 14:08:49

ya_vanka писал(а):Дело в том, что я ставил свойство HTTP.Timeout := 2000, однако эффекта не было. HTTP.HTTPMethod завершался секунд через 15.

Не знаю, должно работать. Может внимательней код пересмотрите и задержка вызвана другими причинами? Кстати, в стабильной версии synapse была проблема, что таймаут для TCP сокетов не отрабатывается на моменте соединения, только на момент самой передачи данных. Может проблема в этом и в FHTTPSend? Рекомендую поэтому попробовать транковую версию synapse, где таймаут для сокетов можно задать и на момент соединения также

ya_vanka писал(а):Вот собственно вопрос как? Как прервать поток не дожидаясь таймаута в HTTP.HTTPMethod? Использовать HTTP.Abort? Он просто выставляет FSock.StopFlag := true. Достаточно ли это для немедленного завершения HTTP.HTTPMethod? Не уверен.

Я имел ввиду некрасивое решение и принудительном завершении потока :(
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho

Сообщение ya_vanka » 11.07.2016 16:36:05

таймаут для TCP сокетов не отрабатывается на моменте соединения, только на момент самой передачи данных


Да, похоже как раз так все и происходит.

Спасибо за ссылки и ответы!
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41


Вернуться в Сеть

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru