gpt4 book ai didi

Delphi,Indy10,如何正确停止和清理连续流上的 readln

转载 作者:行者123 更新时间:2023-12-02 07:32:29 25 4
gpt4 key购买 nike

使用 Delphi 2010 和 Indy10

我正在尝试从 Delphi 读取服务器发送的事件。我已经成功创建了一个线程,它将订阅我的服务器(Python/Flask)上的连接并捕获事件。需要一个线程,因为 HTTP.Get 永远阻塞。我意识到整个协议(protocol)没有实现,但我只对接收从服务器广播的短字符串感兴趣。以下代码有效,但是我无法弄清楚如何在停止程序时干净地停止线程并释放 http_client 和流。

在服务器端,我收到“远程主机强制关闭现有连接”,并且我的程序指示内存泄漏。我尝试了许多不同的组合,试图在不同的点(onTerminate、Destroy)关闭http连接,但我无法让任何东西工作。任何见解或例子将不胜感激。

这是我迄今为止的相关代码:

TSSEThread = class(TThread)
private
url: String;
stream: TMemoryStream;
http_client: TidHTTP;
procedure DoOnWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
public
constructor Create(CreateSuspended: Boolean; url: String);
procedure Execute; override;
end;


constructor TSSEThread.Create(CreateSuspended: Boolean; url: String);
begin
inherited Create(CreateSuspended); // sending False here
Self.FreeOnTerminate := False;
Self.url := url;
end;

procedure TSSEThread.Execute;
begin
inherited;
try
stream := TMemoryStream.Create;
http_client := TIdHTTP.Create(nil);
http_client.OnWork := DoOnWork;
http_client.Request.CacheControl := 'no-cache';
http_client.Request.Accept := 'text/event-stream';
http_client.Response.KeepAlive := True;
while not Terminated do
try
http_client.Get(self.url,stream);
except
on E: Exception do begin
try
http_client.Disconnect;
except
end;
if http_client.IOHandler <> nil then http_client.IOHandler.InputBuffer.Clear;
sleep(3000);
end;
end;
finally
http_client.Free;
stream.Free;
end;
end;

procedure TSSEThread.DoOnWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
var
msg: string;
begin
if self.Terminated then Exit;
SetString(msg,PAnsiChar(stream.Memory),stream.Size);
stream.Position := 0;
if Pos('data:',msg) > 0 then
begin
// Handle msg here. This works fine.
end;
end;

最佳答案

OnWork 事件处理程序中,当线程的 Termination 属性为 true 时,引发异常(例如通过调用 SysUtils.Abort()) 而不是调用 Exit。该异常将中止 HTTP 请求并关闭连接,然后传播到 Execute(),您可以在其中捕获它并再次检查 Termied 以中断您的 while 循环并让您的 finally block 在退出 Execute() 之前释放 TIdHTTP 对象以终止线程。

procedure TSSEThread.DoOnWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
var
msg: string;
begin
//if self.Terminated then Exit;
if self.Terminated then SysUtils.Abort;
...
end;

关于Delphi,Indy10,如何正确停止和清理连续流上的 readln,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23065765/

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