Страница 1 из 1
Подвисание приложения при выполнении THTTPSend.HTTPMethod
Добавлено: 06.07.2016 13:03:37
ya_vanka
Есть приложение, которое в потоке запрашивает файлы с сервера (тайлы Яндекс карт). И все работает, но если в момент вызова 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;
Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho
Добавлено: 06.07.2016 15:27:41
Ichthyander
Непонятно почему у Вас подвисает все приложение, если запрос делается в отдельном потоке. Только этот поток и должен подвисать, в случае, если сервер не отвечает - Вы же вызываете метод HTTPMethod не внутри процедуры Synchronize
Добавлено спустя 1 минуту 38 секунд:
Re: Подвисание приложения при выполнении THTTPSend.HTTPMethod
Может основной поток у Вас просто-напросто ждет завершения потока TLoadMapTileListThread? Тогда будет подвисать. Нужно смотреть код основного потока
Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho
Добавлено: 06.07.2016 15:37:17
ya_vanka
Да, похоже так и было.
Тогда возникают другие вопросы:
1. как настроить время таймаута, чтобы не более 2 секунд выполнялся THTTPSend.HTTPMethod?
2. как моментально завершить поток не дожидаясь таймаута в THTTPSend.HTTPMethod?
Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho
Добавлено: 07.07.2016 04:05:49
Ichthyander
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) завершение потока, которые работает с сервером или просто не дает ему закрыться пока таймаут не будет отработан и поток для работы с сервером сам по себе закроется
Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho
Добавлено: 07.07.2016 11:19:04
ya_vanka
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? Не уверен.
Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho
Добавлено: 07.07.2016 13:08:49
Ichthyander
ya_vanka писал(а):Дело в том, что я ставил свойство HTTP.Timeout := 2000, однако эффекта не было. HTTP.HTTPMethod завершался секунд через 15.
Не знаю, должно работать. Может внимательней код пересмотрите и задержка вызвана другими причинами? Кстати, в стабильной версии synapse была проблема, что таймаут для
TCP сокетов не отрабатывается на моменте
соединения, только на момент самой передачи данных. Может проблема в этом и в FHTTPSend? Рекомендую поэтому попробовать транковую версию synapse, где таймаут для сокетов можно задать и на момент соединения также
ya_vanka писал(а):Вот собственно вопрос как? Как прервать поток не дожидаясь таймаута в HTTP.HTTPMethod? Использовать HTTP.Abort? Он просто выставляет FSock.StopFlag := true. Достаточно ли это для немедленного завершения HTTP.HTTPMethod? Не уверен.
Я имел ввиду
некрасивое решение и принудительном завершении потока

Re: Подвисание приложения при выполнении THTTPSend.HTTPMetho
Добавлено: 11.07.2016 15:36:05
ya_vanka
таймаут для TCP сокетов не отрабатывается на моменте соединения, только на момент самой передачи данных
Да, похоже как раз так все и происходит.
Спасибо за ссылки и ответы!