Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.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
Delphi 不应该';我从不显示来自线程的表单或消息框吗?_Delphi_Delphi 7 - Fatal编程技术网

Delphi 不应该';我从不显示来自线程的表单或消息框吗?

Delphi 不应该';我从不显示来自线程的表单或消息框吗?,delphi,delphi-7,Delphi,Delphi 7,我一直在主线程中显示这样的内容,并使用事件将窗口的结尾与线程同步,以便让它知道窗口何时关闭 今天,在开发过程中,我想将显示的表单从线程移动到主UI,但成功地显示了它。我唯一添加的是,在主线程中,我正在推送等待事件的消息: procedure WaitWithMessageLoop(); var vWaitForEventHandles:array[0..1] of THandle; vWaitForResponse:DWORD; Msg: TMSG; begin vWaitForEventHan

我一直在主线程中显示这样的内容,并使用事件将窗口的结尾与线程同步,以便让它知道窗口何时关闭

今天,在开发过程中,我想将显示的表单从线程移动到主UI,但成功地显示了它。我唯一添加的是,在主线程中,我正在推送等待事件的消息:

procedure WaitWithMessageLoop();
var
vWaitForEventHandles:array[0..1] of THandle;
vWaitForResponse:DWORD;
Msg: TMSG;
begin
vWaitForEventHandles[0] := LServiceMonitor.Handle;
while (1=1) do
begin
  vWaitForResponse := MsgWaitForMultipleObjects(1, vWaitForEventHandles, FALSE, INFINITE, QS_ALLINPUT);
  if (vWaitForResponse = WAIT_OBJECT_0 + 1) then
  begin
    while (PeekMessage(msg,0,0,0,PM_REMOVE)) do
    begin
      TranslateMessage(msg);
      DispatchMessage(msg);
    end;
  end
  else
  if (vWaitForResponse = WAIT_FAILED)
    then RaiseLastOSError
    else break;
end;
end;
所以我的问题是。这样的情景可以接受吗?或者我应该移动一个表单以显示在主线程中


谢谢

您无法在主GUI线程之外可靠地运行VCL表单。当您尝试这样做时,它可能看起来是有效的,但在将来的某个时候,这样的代码将失败。最有可能在您最重要的客户机上,以特别关键的方式


VCL的设计使得所有VCL表单仅从主GUI线程创建和操作。如果需要调用VCL表单,则必须使用诸如
TThread.Synchronize
之类的工具,以确保表单是在GUI线程上创建的。

您没有足够清楚地说明这一切是如何结合在一起的。您正在显示的表单在哪里?当前该表单被实例化并显示在线程中。我正在等待的事件(如上所述)只提供该线程何时完成其任务的信息。(它还推送消息以显示从线程发送的消息)您无法在主GUI线程之外可靠地运行VCL表单。甚至不要想尝试这样做。从主GUI线程运行表单,就像您知道应该做的那样。我假设问题中的代码在线程中运行<代码>当1=1时写得更好
而为True时
。为什么等待成功返回时循环没有中断
WAIT_FAILED
是一个奇怪的终止条件。我发布的代码段在主线程中运行。无论如何,谢谢你,我将移动显示表单的代码。我能接受你的回答吗?:)注意:根据Delphi版本的不同,当主线程由于卡在
TThread.WaitFor
中而无法处理消息时,从线程调用
TThread.Synchronize
,将导致死锁。我认为是Delphi 6和更高版本正确地处理了这个问题,而这个问题是关于Delphi 7的,所以它应该可以正常工作,但我很容易记错了第一个允许这样做的Delphi版本。@hvd-Hmm,但是如果你从主GUI线程调用
TThread.WaitFor
,一切都会中断。这个问题不正是这样问的吗<代码>WaitWithMessageLoop是从主线程调用的,因为主线程正在等待另一个线程完成。在某些情况下,等待其他线程完成是可以接受的,特别是如果您刚刚调用了
TThread.Terminate
并需要等待,直到线程注意到为止。@hvd Yes,但此处的代码使用
MsgWaitForMultipleObjects
,以便windows消息可以中断等待。IIRC这就是
Synchronize
的工作方式。这就是
Synchronize
过去的工作方式,我所说的变化是
Synchronize
现在使用事件,而
TThread.WaitFor
处理
Synchronize
请求。