【问题标题】:Set timeout for InternetReadFile (WinInet + Delphi)为 InternetReadFile 设置超时(WinInet + Delphi)
【发布时间】:2012-07-20 16:56:06
【问题描述】:

我的应用程序需要通过检索其文本内容来处理 url 列表。我的互联网连接开始于

myTimeOut:= 2000;
InternetSetOption(nil, INTERNET_OPTION_CONNECT_TIMEOUT, Pointer(@myTimeOut), SizeOf(myTimeOut));
InternetSetOption(nil, INTERNET_OPTION_SEND_TIMEOUT, Pointer(@myTimeOut), SizeOf(myTimeOut));
InternetSetOption(nil, INTERNET_OPTION_RECEIVE_TIMEOUT, Pointer(@myTimeOut), SizeOf(myTimeOut));

我正在为每个 url 读取启动单独的线程

(...)
read_url_threads[thread_counter]:= TReadURLThread.Create(false);
read_url_threads[thread_counter].FreeOnTerminate:= False;
read_url_threads[thread_counter].myURL:= target_url_list[i];
read_url_threads[thread_counter].output_filename:= local_output_filename;
read_url_threads[thread_counter].NetHandle:= NetHandle;
read_url_threads[thread_counter].limit_text_size:= max_length_url;
hArr[thread_counter]:= read_url_threads[thread_counter].Handle;
(...)
if (thread_counter >= max_threads) or
   (thread_counter >= (target_url_list.Count)) then

   repeat
     rWait:= WaitForMultipleObjects(thread_counter, @hArr,True, 100);
     Application.ProcessMessages;
   until rWait <> WAIT_TIMEOUT;
(...)

在线程执行中,我通过以下方式检索 url 内容:

   if Assigned(NetHandle) and (not EndsText('.pdf',url)) then
    try
      UrlHandle := InternetOpenUrl(NetHandle, PChar(url), nil, 0, 0, 0);
      if Assigned(UrlHandle) then
        try
          repeat
            InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
            SetString(StrBuffer, PAnsiChar(@Buffer[0]), BytesRead);
            Result := Result + StrBuffer;
          until BytesRead = 0;
        finally
          InternetCloseHandle(UrlHandle);
        end;

我的问题是为 InternetReadFile 例程设置超时。有些网址有时会卡住整整几分钟。在此循环中强制超时的最佳方法是什么?

【问题讨论】:

  • 已经在那里了...我希望有一个新的建议。如果没有,如何实现“强制线程超时”(从来没有这样做过......)。我已经实现了线程类。
  • 我认为您也许可以使用 InternetCloseHandle(来自单独的监控线程)。考虑 Indy 的 TIdHTTP,它具有读取超时属性。 Indy 也是跨平台的。

标签: delphi delphi-xe wininet


【解决方案1】:

如果配置的超时没有效果(这是一个已知的错误),那么您应该关闭连接句柄,这将强制关联的函数失败,从而将控制权返回给您的程序。 Microsoft 文章Q224318“如何通过创建第二个线程来控制连接超时值”描述了如何做到这一点。 (您需要一个单独的线程,因为另一个线程卡在等待InternetReadFile 返回。)

【讨论】:

  • 您是否会在主线程中保留一个计时器,遍历上面声明的 read_url_threads 数组并检查辅助线程中的“待添加”start_time 变量?
  • MS 文章的工作链接:mskb.pkisolutions.com/kb/224318
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 2010-09-27
  • 2017-07-31
相关资源
最近更新 更多