Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Delphi TIdTcpServer在超时后强制停止IdSync_Multithreading_Delphi - Fatal编程技术网

Multithreading Delphi TIdTcpServer在超时后强制停止IdSync

Multithreading Delphi TIdTcpServer在超时后强制停止IdSync,multithreading,delphi,Multithreading,Delphi,我需要使用Indy和Delphi XE2开发一个具有持久连接的TCP服务器和客户端。几乎一切都进展顺利 此服务是一项关键服务,因此我需要在服务器中添加一些保护,以防止不必要的处理或冻结。因此,我创建了一个线程来检查关键进程的超时 我制作了这个TIdSync类: type TSync = class(TIdSync) protected procedure DoSynchronize; override; end; procedure TSync.DoSynchronize;

我需要使用Indy和Delphi XE2开发一个具有持久连接的TCP服务器和客户端。几乎一切都进展顺利

此服务是一项关键服务,因此我需要在服务器中添加一些保护,以防止不必要的处理或冻结。因此,我创建了一个线程来检查关键进程的超时

我制作了这个
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;
类型
TSync=class(TIdSync)
受保护的
程序同步;推翻
结束;
程序TSync.DoSynchronize;
变量
oTimeOut:TThreadTimeOut;
开始
...
oTimeOut:=TThreadTimeOut.Create(AContext,WaitTimeOut*2,Self);
oTimeOut.开始;
...
//下面的代码只是一个测试,**这是我问题的关键**
//如果DoSynchronize的任何子例程出错,我希望
//停止执行此对象并销毁它。在上面的线程中
//我想测试超时的时间。如果此IdSync对象仍然存在
//存在,如果此例程仍在执行,我想停止执行
//此对象的任何例程或子例程,以避免冻结
//服务和停止内存消耗和CPU使用
真正的开始
睡眠(100);
结束;
//如果一切顺利
oTimeOut.停下来;
结束;
程序TThreadTimeOut.execute;
变量
初始时间:DWORD;
开始
IniTime:=GetTickCount;
GetTickCount

上述代码可以在超时后停止接收和发送数据,但不能停止执行
TIdSync
。我该怎么做?

TIdSync
中没有超时逻辑(主要是因为
TThread.Synchronize()
中没有超时逻辑,
TIdSync
在内部使用)

无法在
TIdSync
对象运行时销毁该对象。同步过程一旦排队等待执行或已开始运行,就不能过早中止。必须允许它运行到完成

TIdSync.DoSynchronize()
(或与
TThread.Queue()
TThread.Synchronize()
同步的任何方法)在主UI线程的上下文中执行。长时间运行的代码应该在它自己的线程中执行,而不是在主UI线程中执行。确保主UI线程没有被阻止及时处理新消息和同步请求

如果要停止同步过程,需要让它处理一个
TEvent
对象或其他标志,工作线程可以在需要时发出信号,并且该过程会定期检查,以便尽快退出(正常或引发异常)


任何性质的同步操作都应该很短,以防止阻塞/死锁、资源匮乏等。您需要重新思考您的设计。您的做法是错误的。

您的概念是正确的,但我有一个更大的问题,就是这个小代码。在这里,就像上面所说的只是一个例子,但我有一个复杂的加密文本的方法来代替这个。由于这段代码超出了我的控制,我认为甚至不必要在IdSync中实现所有代码。在我的测试中,我看到冻结发生在我运行调试时,但我无法证明这一点,可能是幸运的,但好的程序员不能依赖幸运,您是否有其他建议使代码更加保存,并且可能不会在调试运行时冻结?