我正在修复一个用 C++ 编写的 MFC 应用程序。它是一个 GUI,它与通过 USB 连接到 PC 的外部模块进行通信。
我想避免使用单独的线程。有没有办法可以将东西添加到主循环中,以便它连续运行而不是基于事件?
我希望主循环在每个循环中调用函数 runCommStack()。
我正在修复一个用 C++ 编写的 MFC 应用程序。它是一个 GUI,它与通过 USB 连接到 PC 的外部模块进行通信。
我想避免使用单独的线程。有没有办法可以将东西添加到主循环中,以便它连续运行而不是基于事件?
我希望主循环在每个循环中调用函数 runCommStack()。
当没有消息(如键、鼠标、重绘)到达时,主循环暂停程序,等待下一条消息。所以向主循环添加调用的想法会给你带来非常不稳定的操作。例如,最小化您的窗口将停止所有 USB 通信。
使用 SetTimer 并在 WM_TIMER 处理程序中调用 runCommStack 函数可能会更令人满意。
一些可能的方法:
CWnd::SetTimer
来设置计时器。CWinApp::OnIdle
(由 调用CWinApp::Run
)。CWinApp:Run
、复制和修改原始 MFC 的CWinApp:Run
. 这绝对不是最简单的解决方案。这取决于runCommStack()
. 这个功能运行时间长吗?那么您可能不想在 GUI 线程中运行它。runCommStack 是否需要每 n 毫秒调用一次?那么在它自己的线程中运行它也可能会更好。在其他情况下,您可以只使用计时器或 OnIdle 方法。
关于解决方案 1:正如 Tim 指出的那样,WM_TIMER
消息是低优先级消息,不会传递给应用程序,而其他高优先级消息在消息队列中。另请参见确定窗口消息的优先级。
使用解决方案 2,您应该提醒OnIdle
只有在没有可用的窗口消息时才会调用它。所以这与解决方案 1 完全相同(实际上更糟一些)。
另请记住,如果调用对话框或显示消息框,解决方案 2 和 3 可能会导致您runCommStack
没有被调用。DoModal()
这是因为在MessageBox()
控制期间没有返回CWinApp::Run()
。
我会实施解决方案 1 或 4。
您可以将空闲处理与CWinApp::OnIdle一起使用;如果读取您的 USB 设备只需要很短的时间,这将起作用,否则在长时间读取期间用户界面将被阻止。
但是使用单独的线程绝对是更好的方法。