通过事件关闭模态表单不起作用

SAM*_*Pro -1 delphi

我有一个Modal发送请求的表单(使用idTCpClient).然后在idTCPServer OnExecute事件中,应该关闭该表单(在接收数据之后).

第一个ShowModal;并按Close;预期执行,但第二个close;不起作用,表单仍然可见.

btnClose在表单上放了一个Button()来关闭它.如果我btnClose.Click;在idTCPServer OnExecute事件中使用,表单不会关闭,但如果我手动点击此按钮,表单将被关闭!

我执行这个:

Procedure btnStart();
begin
  Form1.ShowModal;
end;
Run Code Online (Sandbox Code Playgroud)

idTCPServer将执行此操作:

procedure idTCPServerOnExecute(...)
begin
  Form1.close //Or for testing purpose: Form1.btnClose.Click;  
end;
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 5

TIdTCPServer是一个多线程组件.它的OnExecute事件在工作线程中运行,因此无法安全地访问UI组件.

对于您正在尝试的内容,最简单的解决方案是使用TIdNotify该类,例如:

Uses
  ..., IdSync;

procedure TSomeClass.IdTCPServerOnExecute(AContext: TIdContext);
begin
  TIdNotify.NotifyMethod(Form1.Close);
  //Or for testing purpose:
  //TIdNotify.NotifyMethod(Form1.btnClose.Click);
end;
Run Code Online (Sandbox Code Playgroud)

  • **任何**从工作线程直接访问UI组件都是不安全的.随机事情可能发生.它可能**偶然发挥作用,但更可能导致崩溃或死锁.所以就是不要这样做.任何UI访问都需要与主线程同步.`TIdSync`和`TIdNotify`类可以做到这一点,但还有其他方法. (2认同)