Search code examples
jsondelphiindyidhttp

Form blocked while HTTP post does not finish


I am sending JSON to an endpoint and I have a problem. The execution works, but the form gets stuck until HTTP.Post() ends, after it has finished the screen releases for use. I'm sure I'm doing something wrong.

Here is the button action that sends the JSON:

procedure TForm1.Button1Click(Sender: TObject);
var
  HTTP: TIdHTTP;
  vJsonAEnviar: TStringStream;
  Json:String;
begin
  Json := '{ '+
          ' "user":"Lucy"'+
          ' "execute":"ok"'+
          ' } ';
  HTTP := TIdHTTP.Create;
  HTTP.Request.ContentType := 'application/json';
  HTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
  vJsonAEnviar := TStringStream.Create(UTF8Encode(Json));
  HTTP.Post('http://localhost:8080/exportaManual', vJsonAEnviar);
  FreeAndNil(HTTP);
  FreeAndNil(vJsonAEnviar);
end;

On the other side, it takes time to finish and the screen stays blockrd a long time.


Solution

  • You are not doing anything wrong (well, except for a complete lack of any error handling). This is simply how Indy is designed to operate (see Introduction to Indy). Indy uses blocking socket operations. When you perform an operation, the calling thread is blocked until the operation is complete. This is normal.

    If you don't want your UI frozen while the POST is in progress, you can either:

    • drop a TIdAntiFreeze component onto your Form. It will pump UI messages in the background while Indy is blocking the main UI thread.

    • move the POST code to its own worker thread, using TThread, TTask, TIdThreadComponent, etc, and have it notify the main UI thread when finished.