多线程 – 使用TRestRequest进行Delphi线程处理
我对RestRequest工具比较陌生.我希望有人解决了等待异步调用完成的问题……
我有一个程序,它生成数百个不同的api调用,然后调用处理结果,并将结果传递回调用api执行的过程,然后继续… 只有在没有线程的情况下进行此类调用时,问题仍然是软件挂起,直到调用完成…为了尝试解决这个问题,我更改了RESTRequest.Execute;到RESTRequest.ExecuteAsync();,但现在我的问题是我的代码继续而不等待restrequest的响应. 再次尝试绕过这个问题我尝试了几个解决方案,甚至是api.RESTRequest.ExecuteAsync().WaitFor; (抛出错误线程错误:处理程序无效(6)) 有没有什么方法我可以改变下面的函数作为一个单独的线程运行(只有执行部分在线程中运行很重要)…基本上我只想在每次调用函数时显示一个动画加载图标,并且对于我的其余代码来说,直到此功能完成… 我希望有一个更简单的解决方案,而不是开始使用多线程完全.. 码 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; 解决方法
ExecuteAsync()在工作线程(它返回的TRESTExecutionThread对象)中运行.但是,ExecuteAsync()具有默认为True的AFreeThread参数.正如
documentation明确指出:
因此,默认情况下,对返回的对象指针调用WaitFor()将会崩溃. 即使返回的对象指针在AFreeThread = True时有效,调用WaitFor()仍然会崩溃.当TThread对象的FreeOnTerminate属性设置为True时,该对象在线程终止时释放其底层API句柄,这会导致WaitFor()失败并出现“句柄无效”错误. TThread.WaitFor()有一个逻辑错误1,当TThread.FreeOnTerminate = True时,它不处理这种情况. (1这个bug一直在Delphi 6中引入,当时TThread被重写为Kylix支持,并且在以后的版本中从未纠正过.) 如果您希望调用者等待来自REST服务器的响应,请执行以下操作之一: >使用Execute()而不是ExecuteAsync(),或者至少设置AFreeThread = False,这样你就可以在线程对象上调用WaitFor()(或等效的,如MsgWaitForMultipleObjects()),然后处理执行等待的后果主UI线程: 更好的解决方案是根本不等待,这意味着重新设计代码流.继续使用ExecuteAsync(),但传递一个完成回调,该回调将在请求完成时调用,并让该回调驱动代码中的下一步.不要主动等待ExecuteAsync完成,让它通知你. 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; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |