使用wininet下载文件时如何避免冻结
how to avoid freezing when download file using 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;
它在下载小图片时工作正常并且没有卡顿,但是当涉及到大图片时,应用程序在下载完成之前一直卡住,如何避免这种情况?
您的程序正在冻结,因为调用 return 直到下载完成,正如您已经从网络浏览中了解到的那样,有时这可能需要很长时间。发生这种情况时,您的程序不是 运行 正常的事件循环和处理输入。
如果你想让它正常工作,你需要在不同的线程中进行下载。多线程可能非常棘手,但有了正确的库,它就会变得简单得多。对于这样的事情,我建议查看 the Async/Await functionality in OmniThreadLibrary.
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;
它在下载小图片时工作正常并且没有卡顿,但是当涉及到大图片时,应用程序在下载完成之前一直卡住,如何避免这种情况?
您的程序正在冻结,因为调用 return 直到下载完成,正如您已经从网络浏览中了解到的那样,有时这可能需要很长时间。发生这种情况时,您的程序不是 运行 正常的事件循环和处理输入。
如果你想让它正常工作,你需要在不同的线程中进行下载。多线程可能非常棘手,但有了正确的库,它就会变得简单得多。对于这样的事情,我建议查看 the Async/Await functionality in OmniThreadLibrary.