Время соединения не истекает при использовании Indy - PullRequest
5 голосов
/ 06 июля 2010

Я хочу загрузить файл из Интернета, и я думаю, что это должно быть простой задачей.Пробуя несколько разных подходов, я обнаружил, что у каждого есть свой недостаток.Основные проблемы:

  • Приложение зависает до тех пор, пока не загрузит файл
  • Приложение зависает навсегда, если подключение к Интернету потеряно / сервер не отвечает.

(подробности:

Как получить файл из Интернета через HTTP?
Время соединения не истекает при загрузке файла из Интернета )

Итак, наконец, я воспользовался советами нескольких людей по использованию «профессиональных» библиотек, таких как Indy.Тем не менее, Indy не намного лучше, чем фрагменты кода, которые я пробовал (но он намного больше и сложнее в обслуживании).При использовании Indy приложение не зависает только в течение коротких периодов, поэтому оно все еще (каким-то образом) может использоваться.Тем не менее, приложение не может быть закрыто, пока загрузка не закончится (никогда, если подключение к Интернету разрывается).

Другие люди сообщали о той же проблеме: http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200609/0609079112.html
https://forums.embarcadero.com/thread.jspa?threadID=25199&tstart=90

Итак, мне пришлось взломать TIDAntiFreeze, чтобы заставить его работать?

Кроме того, свойство ConnectTimeout не распознается.

fIDHTTP := TIDHTTP.Create(NIL);
fIDHTTP.ConnectTimeout:=5000;

Должен ли я удалить Indy и вернуться к первоначальной идее загрузки файла в отдельном потоке и завершить поток, когда он не отвечает (по крайней мере,таким образом я избавляюсь от сторонних библиотек)?Если я это сделаю, будут непредвиденные побочные эффекты?

Использование: Delphi 7, Indy 10.1.5 10.5 (вероятно).

Спасибо

Ответы [ 2 ]

4 голосов
/ 07 июля 2010

Вам, вероятно, нужно использовать Indy the Indy: использовать потоки.Indy был специально разработан для работы в режиме блокировки, потому что именно так работает большинство интернет-протоколов (пример: с HTTP на уровне протокола вы отправляете запрос, а затем читаете ответ. Вы не отправляете и не получаете одновременно).Предполагается, что TIdAntiFreeze поможет вам использовать некоторые функции Indy без работы с потоками;Я никогда не использовал это, потому что, по крайней мере, концептуально, это уродливый хак.

Если вы не хотите иметь дело с потоками, вам стоит взглянуть на ICS ( ссылка на домашнюю страницу ICS ).ICS был разработан для использования в асинхронном режиме без потоков.Ему не нужен эквивалент TIdAntiFreeze, потому что он не блокирует.Вы начинаете загрузку и обрабатываете некоторые события, чтобы получать уведомления о прогрессе и завершении.ICS так же хорошо известен, профессионален и широко используется как Indy.

0 голосов
/ 07 июля 2010

Не так уж сложно решить подобные проблемы. Первое, что вам нужно сделать, это убедиться, что вы правильно обработали обработку ошибок. Если что-то не получается, убедитесь, что все правильно очищается. Кроме того, убедитесь, что загружаемый код является частью отдельного потока. Если есть какие-либо проблемы, вы всегда можете прекратить поток из вашей основной программы. Вот код (только для загрузки, а не для потоков), который отлично работает для меня.

with TDownloadURL.Create(nil) do
  try
    URL := 'myurltodownload.com';
    filename := 'locationtosaveto';
    try
      ExecuteTarget(nil);
    except
      result := false;
    end;
    if not FileExists(filename) then
      result := false;
  finally
    clear;
    free;
  end;
...