简体   繁体   English

Delphi TIdTcpServer在someTimeOut之后强制停止IdSync

[英]Delphi TIdTcpServer force stop IdSync after someTimeOut

I need to develop a TCP server and client with persistent connections using Indy and Delphi XE2. 我需要使用Indy和Delphi XE2开发具有持久连接的TCP服务器和客户端。 Almost everything is going well. 几乎一切进展顺利。

This service is a critical service, so I need to put in some protection in the server to prevent unnecessary processing or freezes. 此服务是一项关键服务,因此我需要在服务器中加入一些保护,以防止不必要的处理或冻结。 Because of this, I create a thread to check a timeout for critical processes. 因此,我创建了一个线程来检查关键进程的超时。

I made this TIdSync class: 我做了这个TIdSync类:

type
  TSync = class(TIdSync)
  protected
    procedure DoSynchronize; override;
  end;

procedure TSync.DoSynchronize;
var
  oTimeOut: TThreadTimeOut;
begin
  ...
  oTimeOut := TThreadTimeOut.Create(AContext, WaitTimeOut*2, Self);
  oTimeOut.Start;
  ...
  // the code below is just a test, **this is the key to my question**
  // if something goes wrong in any subroutine of DoSynchronize, I want
  // to stop execution of this object and destroy it. In the thread above
  // I want to test when the timeout elapses. If this IdSync object still
  // exists and if this routine is still executing, I want to stop execution
  // of any routine or subroutine of this object to avoid freezing the
  // service and stop memory consumption and CPU usage

  while true do begin
    Sleep(100);
  end;

  //If everything is OK
  oTimeOut.Stop;
end;

procedure TThreadTimeOut.execute;
var
  IniTime: DWORD;
begin
  IniTime := GetTickCount;
  while GetTickCount < IniTime + TimeOut  do begin
    Sleep(SleepInterval);
    if StopTimeOut then
       Exit;
  end;

  if ((Terminated = False) or (StopTimeOut)) and (IoHandler <> nil)  then begin
    IOHandler.Connection.IOHandler.Close;
    IdSync.Free; //here I try to make things stop execution but the loop to test is still running
  end;
end;

This code above works fine to stop receiving and sending data when the timeout elapses, but not to stop execution of TIdSync . 上面的这段代码可以很好地用于在超时后停止接收和发送数据,但是不能停止执行TIdSync How can I do that? 我怎样才能做到这一点?

There is no timeout logic in TIdSync (largely because there is no timeout logic in TThread.Synchronize() , which TIdSync uses internally). TIdSync没有超时逻辑(主要是因为TIdSync内部使用的TThread.Synchronize()没有超时逻辑)。

You cannot destroy a TIdSync object while it is running. 您不能在TIdSync对象运行时销毁它。 A synced procedure cannot be aborted prematurely once it has been queued for execution, or has started running. 同步过程已排队等待执行或开始运行后, 无法过早中止。 It must be allowed to run to completion. 必须允许它运行完成。

TIdSync.DoSynchronize() (or any method synced with TThread.Queue() or TThread.Synchronize() ) is executed in the context of the main UI thread. TIdSync.DoSynchronize() (或与TThread.Queue()TThread.Synchronize()同步的任何方法TThread.Queue()在主UI线程的上下文中执行。 Long-running code should be executed in its own thread, not in the main UI thread. 长时间运行的代码应在其自己的线程中执行,而不应在主UI线程中执行。 Make sure the main UI thread is not blocked from processing new messages and sync requests in a timely manner. 确保未阻止主UI线程及时处理新消息和同步请求。

If you want to stop a synced procedure, you need to have it handle a TEvent object or other flag which worker threads can signal when needed, and that the procedure checks periodically so it can exit as soon as possible (either gracefully or by raising an exception). 如果要停止同步的过程,则需要让它处理TEvent对象或其他标志,以便工作线程在需要时可以发出信号,并且该过程会定期检查,以便可以尽快退出(正常运行或通过引发例外)。

Synched operations of any nature should be short, to prevent blockages/deadlocks, resource starvation, etc. You need to re-think your design. 任何性质的同步操作都应简短,以防止阻塞/死锁,资源匮乏等。您需要重新考虑设计。 You are doing things the wrong way. 您做事的方式是错误的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM