gpt4 book ai didi

multithreading - Delphi:如何从 idHTTPServer.OnCommandGet 方法在主线程中执行过程

转载 作者:行者123 更新时间:2023-12-03 13:15:56 26 4
gpt4 key购买 nike

我必须在我们的应用程序中创建一个嵌入式 HTTP 服务器。这必须创建用于进程间通信,因为另一端只能调用 WebService。

我们不需要一次处理更多请求,但我必须从主线程使用库和数据库连接。

Delphi 版本是 Seattle,Indy 版本是 10(内部)。

据我所知,IdHTTPServer 像以前一样使用线程进行连接。但是新的事件处理程序不直接传递 Thread - 所以我不能像 N 年前那样调用 TThread.Synchronize。而且我没有找到任何获取线程的方法。

我在某处读到 TIdSync 或 TIdNotify 类可以帮助我。我找不到任何完整的示例来了解如何操作。

请看这段简单的代码。在主线程中完成我的工作是否足够?

procedure TForm5.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
begin
FURI := ARequestInfo.URI; // Store the URI for main thread access
FResult := '';
TIdSync.SynchronizeMethod(Self.ProcessIt); // Call sync to process in VCL thread
AResponseInfo.ContentText := FResult; // This variable contains the result
end;

还是我做错了什么?

谢谢你的帮助!

最佳答案

有一种方法可以访问 TIdContext 背后的底层 TThread - 将 TIdContext.Yarn 属性类型转换为 TIdYarnOfThread 然后访问它的 Thread 属性,例如:

procedure TForm5.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
Thread: TThread;
begin
Thread := (AContext.Yarn as TIdYarnOfThread).Thread;
FURI := ARequestInfo.URI;
FResult := '';
Thread.Synchronize(ProcessIt);
AResponseInfo.ContentText := FResult;
end;

但是,在您的情况下您实际上并不需要它,因为 TThread.Synchronize() (和 TThread.Queue() )具有 class 方法重载,因此您不需要 TThread 对象来调用它,例如:

procedure TForm5.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
FURI := ARequestInfo.URI;
FResult := '';
TThread.Synchronize(nil, ProcessIt);
AResponseInfo.ContentText := FResult;
end;

TIdSync(和 TIdNotify)确实可以代替使用,您拥有的是一个好的开始,它只需要再充实一点对 FURIFResult 变量的访问也是同步的,以防您需要一次处理多个客户端连接,因此需要避免并发访问到变量,例如:

type
TIdProcessItSync = class(TIdSync)
URI: string;
Content: string;
protected
procedure DoSynchronize; override;
end;

procedure TIdProcessItSync.DoSynchronize;
begin
Content := Form5.ProcessIt(URI);
end;

function TForm5.ProcessIt(const URI: string): String;
begin
Result := ...;
end;

procedure TForm5.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
Sync: TIdProcessItSync;
begin
Sync := TIdProcessItSync.Create;
try
Sync.URI := ARequestInfo.URI;
Sync.Synchronize;
AResponseInfo.ContentText := Sync.Content;
finally
Sync.Free;
end;
end;

也就是说,TIdSync(和 TIdNotify)已被弃用,取而代之的是 TThreadclass 方法支持 anonymous procedures 的重载,例如:

function TForm5.ProcessIt(const URI: string): String;
begin
Result := ...;
end;

procedure TForm5.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
URI, Content: String;
begin
URI := ARequestInfo.URI;
TThread.Synchronize(nil,
procedure
begin
Content := ProcessIt(URI);
end
);
AResponseInfo.ContentText := Content;
end;

或者:

function TForm5.ProcessIt(const URI: string): String;
begin
Result := ...;
end;

procedure TForm5.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
TThread.Synchronize(nil,
procedure
begin
AResponseInfo.ContentText := ProcessIt(ARequestInfo.URI);
end
);
end;

关于multithreading - Delphi:如何从 idHTTPServer.OnCommandGet 方法在主线程中执行过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65146405/

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