Multithreading – Delphi threading using trestrequest

I am new to restrequest tool I hope someone has solved the problem of waiting for asynchronous calls to complete

I have a program that generates hundreds of different API calls, then calls the result of the processing, passes the result back to the API execution process, and continues.

Only when such a call is made without a thread, the problem is still that the software hangs until the call is completed... In order to try to solve this problem, I changed restrequest Execute; To restrequest ExecuteAsync();, But now my problem is that my code continues without waiting for a response from restrequest

Trying to bypass this problem again, I tried several solutions, even API RESTRequest. ExecuteAsync(). WaitFor; (throw error thread error: invalid handler (6))

Is there any way I can change the following function to run as a separate thread (only the execution part runs in the thread is very important)... Basically, I just want to display an animation loading icon every time I call the function, and for the rest of my code, until this function is completed

I want a simpler solution instead of starting using multithreading completely

code

function run_api_command():boolean;
begin

  result := false;
  RESTResponse.Content.Empty;
  RESTAdapter.Dataset:= ds_action;
  RESTAdapter.RootElement:= '';

  try
    RESTRequest.ExecuteAsync;

    if(ds_action.Active = false) then ds_action.Active:=true;
    if(ds_action.FieldByName('result').AsString<>'Success') then
      begin
        showmessage(ds_action.FieldByName('result').AsString);
      end
    else
      begin
        RESTAdapter.RootElement:= 'data';
        result := true;
      end;
  except
    on E: Exception do
      begin
        if(e.Message = 'REST request Failed: Error sending data: (12007) The server name or address Could not be resolved') then
          begin
            if(messagedlg('Could not connect to server. Would you like to retry?',mterror,[mbYes,mbNo],0)=mrYes) then
              begin
                result := run_api_command();
              end;
          end
        else
          begin
            showmessage(RESTResponse.Content);
          end;
      end;
  end;
end;

Solution

Executeasync () runs in the worker thread (the trestexecutionthread object it returns) However, executeasync() has an afreethread parameter that defaults to true As the documentation clearly states:

Therefore, by default, calling waitfor () on the returned object pointer will crash

Even if the returned object pointer is valid when afreethread = true, calling waitfor() will still crash When the freeonterminate property of the TThread object is set to true, the object releases its underlying API handle when the thread terminates, which will cause waitfor() to fail with an "invalid handle" error TThread. Waitfor() has a logic error 1 when TThread When freeonterminate = true, it does not handle this situation

(1 this bug has been introduced in Delphi 6. At that time, TThread was rewritten as Kylix support, and it has never been corrected in later versions.)

If you want the caller to wait for a response from the rest server, do one of the following:

>Use execute() instead of executeasync(), or at least set afreethread = false, so that you can call waitfor() (or equivalent, such as msgwaitformultipleobjects()) on the thread object, and then deal with the consequences of execution waiting. Main UI thread: > use execute() but move the whole logic to your own worker thread and synchronize it with the main UI thread as needed

A better solution is not to wait at all, which means redesigning the code flow Continue to use executeasync(), but pass a completion callback that will be called when the request completes and let the callback drive the next step in the code Don't actively wait for executeasync to complete, let it notify you

procedure run_api_command();
begin
  ...
  RESTRequest.ExecuteAsync(
    procedure
    begin
      if not RESTResponse.Status.Success then
      begin
        // do something ...
      end else begin
        // do something else ...
      end;
    end,True
  );
end;
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>