delphi - 使用 wininet 下载文件时如何避免卡住

标签 delphi wininet

iam 使用 wininet 下载图像并将其保存到内存流这是我的程序

procedure DownloadToStream(const Url: string; ms: TMemoryStream);
var
  hSession     : HINTERNET;
  hService     : HINTERNET;
  lpBuffer     : array[0..1023] of Byte;
  dwBytesRead  : DWORD;
  dwBytesAvail : DWORD;
  dwTimeOut    : DWORD;
begin
  hSession := InternetOpen('usersession', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if not Assigned(hSession) then Exit;
  try
    hService := InternetOpenUrl(hSession, PChar(Url), nil, 0, 0, 0);
    if hService = nil then
      Exit;
    try
      dwTimeOut := 60000;
      InternetSetOption(hService, INTERNET_OPTION_RECEIVE_TIMEOUT, @dwTimeOut, SizeOf(dwTimeOut));
      if InternetQueryDataAvailable(hService, dwBytesAvail, 0, 0) then
      repeat
        if not InternetReadFile(hService, @lpBuffer[0], SizeOf(lpBuffer), dwBytesRead) then
          Break;
        if dwBytesRead <> 0 then
          ms.WriteBuffer(lpBuffer[0], dwBytesRead);
      until dwBytesRead = 0;
    finally
      InternetCloseHandle(hService);
    end;
  finally
    InternetCloseHandle(hSession);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ms: TMemoryStream;
begin
  ms := TMemoryStream.Create;
  try
    DownloadToStream('imageurl, ms);
    ms.Position := 0;
    //do whatever you want with ms
  finally
    ms.Free;
  end;
end;

它在下载小图像时工作正常并且没有卡住,但当涉及大图像时,应用程序会卡住直到下载完成,如何避免这种情况?

最佳答案

您的程序卡住,因为在下载完成之前调用不会返回,正如您从网页浏览中已经知道的那样,有时这可能需要很长时间。当发生这种情况时,您的程序没有运行正常的事件循环和处理输入。

如果您想让它正常工作,您需要在不同的线程中进行下载。多线程可能非常棘手,但是有了正确的库,它就会变得简单得多。对于这样的事情,我建议查看 the Async/Await functionality in OmniThreadLibrary.

关于delphi - 使用 wininet 下载文件时如何避免卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30140596/

相关文章:

c++ - WinInet - 301重定向后如何获取服务器URL?

delphi - Indy 9 + Delphi 2007 最新的 SSL 库可用吗?

android - Android 和 iOS 上的 ipv6 和 TidHTTP 问题

Delphi窗体没有系统菜单但有关闭按钮

delphi - 如何获取提升进程的进程句柄?

ftp - IE 11 中的 wininet 为大多数 FTP 功能随机返回错误 12003

delphi - 在 Delphi 中,OnIncludeItem 事件如何在 TOpenDialog 上工作?

visual-c++ - 将互联网句柄设置为静态成员并在线程外部访问它..需要专家建议

ssl - Wininet SSL,每个请求都具有客户端证书智能卡访问权限

c - Wininet 不向服务器发送 cookie