Delphi 如何终止所有活动连接并停止IdTCPServer?Indy10

Delphi 如何终止所有活动连接并停止IdTCPServer?Indy10,delphi,indy10,Delphi,Indy10,开放式连接 IdTCPServer.Active:=false; 导致程序挂起。 如何终止所有活动连接并停止IdTCPServer? 我正在努力做到以下几点: procedure TMyServer.Stop; var List: TList; i: Integer; begin List := Contexts.LockList; try for i := List.Count - 1 downto 0 do begin TMyContext(List.It

开放式连接 IdTCPServer.Active:=false; 导致程序挂起。 如何终止所有活动连接并停止IdTCPServer? 我正在努力做到以下几点:

procedure TMyServer.Stop;
var
  List: TList;
  i: Integer;
begin
  List := Contexts.LockList;
  try
    for i := List.Count - 1 downto 0 do begin
      TMyContext(List.Items[i]).WaitDisconnect := True;
    end;
  finally
    Contexts.UnlockList;
  end;
  // Active := False;
  Timer.OnTimer := ProcTimer;
  Timer.Enabled := True;
end;

TMyContext = class(TIdServerContext)
public
  WaitDisconnect: Boolean;
end;


procedure TMyServer.Execute(AContext: TIdContext);
var
  Ctx: TMyContext;
begin
  Ctx := TMyContext(AContext);

  if not Ctx.WaitDisconnect then begin
     //read data
  else begin
    TMyContext(AContext).Connection.Disconnect;
  end;
end;

procedure TMyServer.ProcTimer(Sender: TObject);
var
  ClientsCount: Integer;
begin
  with Contexts.LockList do 
  try
    ClientsCount := Count;
  finally
    Contexts.UnlockList;
  end;

  if ClientsCount = 0 then begin
    Active := False;
    Timer.Enabled := False;
  end;
end;
打开连接时IdTCPServer.Active:=false;导致程序挂起

发生这种情况的唯一方法是将服务器死锁

如果在服务器的事件处理程序同时与主UI线程同步时从主UI线程的上下文中停用服务器,则可能会发生这种情况(
TIdSync
TThread.Synchronize()
SendMessage()
,等等)

如果您的客户端线程正在做一些不安全的事情,比如在没有正确同步的情况下访问UI,也可能发生这种情况

停用服务器将关闭所有活动套接字并等待其线程终止。但是,如果一个或多个客户端线程在等待主UI线程时被阻塞,或者在其他方面被死锁,并且主UI线程在等待服务器停用时被阻塞,那么这就是挂起程序的死锁

要解决这个问题,您需要确保服务器代码是线程安全的,并且您可以:

  • 使用异步同步(
    TIdNotify
    TThread.Queue()
    PostMessage()
    ,等等),这样客户端线程就不会被阻止在主UI线程上等待

  • 从工作线程停用服务器,以便主UI线程可以正常处理同步请求


使用异步同步,以便服务器的客户端线程不会在等待主UI线程时被阻塞。(Indy不支持)从工作线程停用服务器,以便主UI线程不会被阻止处理同步请求。(你能找到一个例子吗?@Alex 1)Indy确实支持异步同步(
TIdNotify
TThread.Queue()
)。2) 只需调用
TThread.CreateAnonymousThread()
TTask.Create()
即可运行将
Active=False设置为