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?

+3


source to share


1 answer


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.

+3


source







All Articles