【问题标题】:TThread Doesn't Do It's Job Unless there is a MessageBox in the Middle !除非中间有 MessageBox,否则 TThread 不会做它的工作!
【发布时间】:2011-07-21 07:23:07
【问题描述】:

我创建了一个 TThread 类来执行一些套接字操作,问题是,除非我向其中添加 MessageBox,否则代码不起作用,除非我在它之前放置 MessageBox 调用,否则套接字将不起作用

 Sleep(2000); //Waiting for the Socket to Come to the Array
 // Messagebox(0, '', '', 0); { Wont work unless this line is Uncommented }
 if Server.ClientList[Handle] <> nil then
 begin
  if (Server.ClientList[Handle].Connected) and (AppSocket.Connected) do
  begin
   // Send Data on Socket
   // Relay Data between Server.ClientList[Handle] and AppSocket;
  end; 

【问题讨论】:

  • 我的想法是 TCP 通信可能需要一个消息队列来处理,而 MessageBox 正在提供该功能。
  • @mj2008,我也想过,但这很奇怪:MessageBox 肯定会在显示时发送消息,但是一旦结束,就不会再发送消息了,因为 OP 没有提到实现消息泵。可能有足够多的消息在盒子出现在屏幕上时通过,从而制造出在通话之后一切正常的错觉,但事实上,所有可用的数据都是在消息出现在屏幕上时使其低谷的数据。
  • 到底谁认为阻止我们在 cmets 中使用多个 @usernames 是个好主意?! Stack Overflow 过去的业务是让我们更容易沟通。非常糟糕的决定。有人为用户着想!
  • 绝对是消息泵问题;不看更多代码就无法说出更多。
  • 正如其他海报所强调的那样,在辅助线程中使用基于 Windows 消息的 TCP 系统是不可取的,这一行也有些令人担忧:'Sleep(2000); //等待套接字进入数组'。这可能很好,但是当线程死了两秒钟时发生了什么?

标签: multithreading delphi delphi-7 tthread


【解决方案1】:

假设您使用的是非阻塞套接字,那么您的线程需要一个正在运行的消息队列和处理循环。这就是调用MessageBox() 起作用的原因——它是一个模态对话框,在内部抽取调用线程的消息队列。您的线程需要在连接的生命周期内循环调用PeekMessage()GetMessage()。您的循环可以使用MsgWaitForMultipleObjects() 来检测消息队列何时需要处理,如果您的线程还有其他需要做的事情。

【讨论】:

  • 我连续调用了 GetMessage()、TranslateMessage() 然后 DisposeMessage,但这并没有解决它(虽然我调用了它一次,在同一个地方我调用了 MessageBox API)
  • 只调用一次是不够的。就像我说的那样,您需要在线程管理的连接的整个生命周期内不断地为新消息发送队列。
【解决方案2】:

尝试将 Messagebox() 替换为 Application.ProcessMessages,看看会发生什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    相关资源
    最近更新 更多