gpt4 book ai didi

multithreading - 线程单元-输出到主应用程序

转载 作者:行者123 更新时间:2023-12-03 18:36:58 25 4
gpt4 key购买 nike

我目前正在尝试为线程创建一个统一的单元。我已经开发了一个Web API,打算与多个应用程序一起使用。我对线程的意图是不使用主应用程序线程就从API获取数据。 (即,为了获得良好的用户体验,将其卸载到线程中)。将使用对API的POST请求通过JSON检索输出,然后从那里执行解析。

我已经把所有单元都写好了,但是我正在努力弄清楚如何在实际应用程序中检索输出/如何将JSON从线程传输到应用程序。

我认为我需要在某个位置添加“输出变量”,但是我不确定当该单元是独立单元时该怎么做-通常我会全部写在一个单元中,当然我可以将其输出到全局单元中那里可变。

这是我的线程单元;

unit TCAPI_ThreadLib;

interface

uses
FMX.Types, FMX.Objects, {FMX.Dialogs,} IdHTTP, System.Classes;

type
TTCAPI_GetJson_Thread = class(TThread)
private
APIHTTP : TIdHTTP;
FApiEmail, FApiId, FApiPassword, FCommand, FCommandParams : String;
protected
procedure Execute; override;
procedure Finished;
public
constructor Create(SEmail, SApiID, SAPIPassword : String);
destructor Destroy; override;
var
FDevGUID, FDevFN, FDevPlatform, FDevModel : String;
FApiDataResult : String;
Const
APIBase : String = 'http://my-web-api-url.com/api.php';
end;

implementation

{ TTCAPI_GetJson_Thread }
constructor TTCAPI_GetJson_Thread.Create(SEmail, SApiID, SAPIPassword: String);
begin
inherited Create(True);
APIHTTP := TIdHTTP.Create(nil);
FApiEmail := SEmail;
FApiID := SApiID;
FApiPassword := SApiPassword;
FreeOnTerminate := True;
end;

destructor TTCAPI_GetJson_Thread.Destroy;
begin
APIHttp.Free;
inherited;
end;

procedure TTCAPI_GetJson_Thread.Execute;
var
RcvStrm : TStringStream;
TmpClass : String;
ApiCommand : String;
_Params : TStringList;
begin
inherited;
RcvStrm := TStringStream.Create;
_Params := TStringList.Create;
_Params.Add('API_ID='+FApiID);
_Params.Add('API_EMAIL='+FApiEmail);
_Params.Add('API_PASSWORD='+FApiPassword);
APICommand := APIBase;

try
APIHTTP.Post(APICommand, _Params, RcvStrm);
FApiDataResult := RcvStrm.DataString;
finally
RcvStrm.Free;
_Params.Free;
end;
Synchronize(Finished);
end;

procedure TTCAPI_GetJson_Thread.Finished;
begin
// ShowMessage(FApiDataResult);
end;

end.

如果我在线程单元中添加 FMX.Dialogs并使用 ShowMessage(FApiDataResult)调用,它将在消息框中显示JSON-我需要弄清楚如何将JSON转换为应用程序主体/表单范围内的变量,以及如何实际告诉应用程序线程已完成,以便我可以开始解析。

我敢肯定这很简单,但是我将不胜感激!

最佳答案

经过更多的研究,我找到了一个涉及回调的解决方案。发布以供将来引用(当然也可以与其他人分享知识以寻求答案);

unit TCAPI_ThreadLib;

interface

uses
FMX.Types, FMX.Objects, IdHTTP, System.Classes;

type
TDataCallback = Procedure(const SJson : String) of Object;

TTCAPI_GetJson_Thread = class(TThread)
constructor Create(SEmail, SApiID, SAPIPassword : String; CallBack : TDataCallback); overload;
procedure Execute; override;
destructor Destroy; override;

private
APIHTTP : TIdHTTP;
FApiEmail, FApiId, FApiPassword, FCommand, FCommandParams : String;
FApiDataResult : String;
FDataProc : TDataCallback;
FDevGUID, FDevFN, FDevPlatform, FDevModel : String;
Procedure DoCallback;
public
Const
APIBase : String = 'http://my-web-api-url.com/api.php';
end;

implementation

{ TTCAPI_GetJson_Thread }
procedure TTCAPI_GetJson_Thread.DoCallback;
begin
if Assigned(FDataProc) then FDataProc(FApiDataResult);
end;

constructor TTCAPI_GetJson_Thread.Create(SEmail, SApiID, SAPIPassword: String; CallBack : TDataCallback);
begin
inherited Create(True);
APIHTTP := TIdHTTP.Create(nil);
FApiEmail := SEmail;
FApiID := SApiID;
FApiPassword := SApiPassword;
FDataProc := Callback;
end;

destructor TTCAPI_GetJson_Thread.Destroy;
begin
APIHttp.Free;
inherited;
end;

procedure TTCAPI_GetJson_Thread.Execute;
var
RcvStrm : TStringStream;
TmpClass : String;
ApiCommand : String;
_Params : TStringList;
begin
inherited;
RcvStrm := TStringStream.Create;
_Params := TStringList.Create;
_Params.Add('API_ID='+FApiID);
_Params.Add('API_EMAIL='+FApiEmail);
_Params.Add('API_PASSWORD='+FApiPassword);
APICommand := APIBase;

try
APIHTTP.Post(APICommand, _Params, RcvStrm);
FApiDataResult := RcvStrm.DataString;
finally
RcvStrm.Free;
_Params.Free;
end;
Synchronize(DoCallback);
end;

end.

在我的主要申请单位内;
Procedure TForm1.DataCallback(Const S: String);
begin
ShowMessage(S);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
DataThread : TTCAPI_GetJson_Thread;
begin
With TTCAPI_GetJson_Thread.Create('email@example.com','apiid','password', DataCallback) do
begin
FreeOnTerminate := True;
Start;
end;
end;

这使我可以将线程单元与我的应用程序单元完全分开,这是我构建 future 单元的真正坚实基础。

关于multithreading - 线程单元-输出到主应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21176345/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com