gpt4 book ai didi

multithreading - Indy 10 IdTCPClient 使用单独的线程读取数据?

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

问题:我正在寻找的是在 Indy 10 中使用单独线程通过 IdTCPClient 接收数据的最典型或最佳实践方法。

背景:下面的代码是我尝试对实际数据处理部分执行的操作示例,为了清楚起见,删除了实际数据处理部分。线程的想法是接收所有数据(可变大小,带有声明消息其余长度的 header ),然后解析它(这就是 HandleData 过程的作用)并根据命令触发事件处理程序。

主应用程序将 TIdIOHandlerSocket 传递给线程,主应用程序还会在需要时将数据写入套接字。

TScktReceiveThread = class(TThread)
private
{ Private declarations }
procedure HandleData;
protected
procedure Execute; override;
public
FSocket: TIdIOHandlerSocket;
constructor Create(CreateSuspended: boolean);
end;


procedure TScktReceiveThread.Execute;
var
FixedHeader: TBytes;
begin
Assert(FSocket <> nil, 'You must assign the connected socket to the receiving thread');
SetLength(FixedHeader, 2);
while not Terminated do
begin
if not FSocket.Connected then
Suspend
else
begin
FSocket.CheckForDataOnSource(10);
if not FSocket.InputBufferIsEmpty then
begin
FSocket.ReadBytes(FixedHeader, SizeOf(FixedHeader), false);
// Removed the rest of the reading and parsing code for clarity
Synchronize(HandleData);
end;
end;
end;
end;

作为前缀,我使用了另一个处理 Indy 的服务器组件的 StackOverflow 问题:“Delphi 2009, Indy 10, TIdTCPServer.OnExecute, how to grab all the bytes in the InputBuffer ”来获取迄今为止我所拥有的基础。

感谢您的帮助!

最佳答案

如果您想避免为每个客户端-服务器数据交换创建线程类所带来的开销,您可以创建一个移动线程类,如

http://delphidicas.blogspot.com/2008/08/anonymous-methods-when-should-they-be.html

几天前我遇到了同样的问题,我刚刚编写了一个类 TMotileThreading,它具有静态函数,可以让我使用 D2009 的新匿名方法功能创建线程。看起来像这样:

type
TExecuteFunc = reference to procedure;

TMotileThreading = class
public
class procedure Execute (Func : TExecuteFunc);
class procedure ExecuteThenCall (Func : TExecuteFunc; ThenFunc : TExecuteFunc);
end;

第二个过程允许我像您的情况一样执行客户端-服务器通信,并在数据到达时执行一些操作。匿名方法的好处是您可以使用调用上下文的局部变量。所以通信看起来像这样:

var
NewData : String;
begin
TMotileThreading.ExecuteThenCall (
procedure
begin
NewData := IdTCPClient.IOHandler.Readln;
end,
procedure
begin
GUIUpdate (NewData);
end);
end;

Execute 和 ExecuteThenCall 方法只是创建一个工作线程,将 FreeOnTerminate 设置为 true 以简化内存管理,并在工作线程的 Execute 和 OnTerminate 过程中执行提供的函数。

希望有帮助。

编辑(根据要求完整实现 TMotileThreading 类)

type
TExecuteFunc = reference to procedure;

TMotileThreading = class
protected
constructor Create;
public
class procedure Execute (Func : TExecuteFunc);
class procedure ExecuteAndCall (Func : TExecuteFunc; OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean = False);
end;

TMotile = class (TThread)
private
ExecFunc : TExecuteFunc;
TerminateHandler : TExecuteFunc;
SyncTerminateHandler : Boolean;
public
constructor Create (Func : TExecuteFunc); overload;
constructor Create (Func : TExecuteFunc; OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean); overload;
procedure OnTerminateHandler (Sender : TObject);
procedure Execute; override;
end;

implementation

constructor TMotileThreading.Create;
begin
Assert (False, 'Class TMotileThreading shouldn''t be used as an instance');
end;

class procedure TMotileThreading.Execute (Func : TExecuteFunc);
begin
TMotile.Create (Func);
end;

class procedure TMotileThreading.ExecuteAndCall (Func : TExecuteFunc;
OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean = False);
begin
TMotile.Create (Func, OnTerminateFunc, SyncTerminateFunc);
end;

constructor TMotile.Create (Func : TExecuteFunc);
begin
inherited Create (True);
ExecFunc := Func;
TerminateHandler := nil;
FreeOnTerminate := True;
Resume;
end;

constructor TMotile.Create (Func : TExecuteFunc; OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean);
begin
inherited Create (True);
ExecFunc := Func;
TerminateHandler := OnTerminateFunc;
SyncTerminateHandler := SyncTerminateFunc;
OnTerminate := OnTerminateHandler;
FreeOnTerminate := True;
Resume;
end;

procedure TMotile.Execute;
begin
ExecFunc;
end;

procedure TMotile.OnTerminateHandler (Sender : TObject);
begin
if Assigned (TerminateHandler) then
if SyncTerminateHandler then
Synchronize (procedure
begin
TerminateHandler;
end)
else
TerminateHandler;
end;

关于multithreading - Indy 10 IdTCPClient 使用单独的线程读取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/554142/

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