我的主窗体有一个 Indy 阻塞套接字,我想在应用程序启动并显示主窗体后立即连接并阻塞它。
你真的需要在主 UI 线程中做阻塞 I/O 吗?阻塞操作,例如 Indy 的套接字 I/O,应该在工作线程中完成。
如果主线程在处理 UI 消息时需要阻塞套接字操作,您可以通过CreateEvent()
with在循环中使用可等待事件对象,该对象仅在有消息要处理时MsgWaitForMultipleObject()
调用,在事件发出信号时中断循环。Application->ProcessMessages()
不过,这通常不是最好的选择。一个事件驱动模型,其中工作线程通知主线程活动/结果,将是一个更好的选择。你真的不应该为任何事情阻塞主 UI 线程。
这样做的正确方法是什么?
我建议让 MainForm 构造函数创建一个工作线程,然后该线程可以管理套接字操作并在需要时与主 UI 同步。
在以前的版本或 C++Builder 中,OnCreate 和 AfterConstruction 都是不可靠的。
AfterConstruction()
是可靠的,而且一直都是。它只是OnCreate
不可靠的事件,并且永远不应该在 C++ 中用于支持构造函数。
通常我将这样的代码放在主 .cpp 文件中,就在 Application->Run() 之前,但是在这里不合适,因为我要阻塞(并依赖 TIdAntifreeze 进行消息处理)。
你真的不应该依赖TIdAntiFreeze
,工作线程是更好的选择。
我想到的一种方法是定义一个自定义窗口消息并将其发布给自己
那可行。我自己有时也会使用这种技术。请注意,这是一个HWND
基于 - 的解决方案,因此您需要确保在HWND
发布消息之后以及从消息队列中检索到之前,您发布的内容不会被破坏/重新创建。如果您使用 MainForm 的,请在事件HWND
中发布消息。OnShow
更好的选择是使用为您的自定义消息AllocateHWnd()
创建专用的。HWND