How to avoid freezing when uploading a file using wininet
iam using wininet to load an image and save it to a memory stream, here is my procedure
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;
it works fine and does not freeze when loading small images, but when it comes to large images the application freezes until the download is done, how to avoid this?
source to share
Your program freezes because the call doesn't return until the download is complete, and as you already know from the web browser, this can sometimes take a long time. While it does, your program does not start the normal event loop and log in for processing.
If you want it to work properly, you need to do the upload on a different thread. Multithreading can be very complex, but with the right libraries it becomes much easier. For something similar, I suggest taking a look at the Async / Await function in the OmniThreadLibrary.
source to share