因此,Windows 事件处理中存在一个严重缺陷:处理网络 I/O 的最佳方式,尤其是在有许多连接的情况下,是通过 I/O 完成端口 (IOCP)。然而,不幸的是,Windows 无法让线程在同一线程中等待 IOCP 事件和 GUI 事件。这似乎是 Win32 API 中的一个严重设计缺陷,但几十年来一直如此。更奇怪的是,内部 NT 内核 API 实际上支持替代方案(特别是,它们允许通过 APC 传递 I/O 完成事件)但 Microsoft 尚未公开这些 API,因此使用它们的应用程序将来可能会中断Windows 版本。
因此,基本上有两种方法可以设计同时进行网络 I/O 和实现 GUI 的程序:
使用MsgWaitForMultipleObjectsEx
基于 - 的事件循环而不是 IOCP。您将被限制为不超过 64 个连接,并且事件循环将相对低效。
网络和 GUI 有单独的线程。
对于您的用例,听起来 #1 可能会很好,但还有另一个问题:KJ 事件循环库(由 Cap'n Proto 使用)尚未实现这种情况。它只实现基于 IOCP 的网络。Win32WaitObjectThreadPool
定义了一个类kj/async-win32.h
来处理 GUI 事件循环方法……但目前它还没有实现。(如果您愿意贡献,欢迎 PRs!)
如果您真的不关心及时处理 GUI 事件,那么也许黑客会起作用:您可以使用kj::Timer
创建一个等待一秒钟的循环,然后检查 Win32 GUI 事件队列,然后再次等待,等等上。这真的很难看,但可能很容易实现。我不确定是否kj::Timer
通过 EZ-rpc 公开,因此您可能不得不kj::setupAsyncIo()
转而使用较低级别的构建块。