How can worker threads communicate with main UI thread?(工作线程如何与主 UI 线程通信?)
问题描述
工作线程与主 UI 线程通信的最佳方式是什么?
What is the best way for worker threads to communicate with the main UI thread?
总结:我的 C++/MFC 应用程序是基于对话框的.为了进行冗长的计算,主 UI 线程创建了几个工作线程.当工作线程在计算中进行时,它们会将其进度报告给主 UI 线程,然后主 UI 线程会显示进度.
Summary: My C++/MFC application is dialog-based. To do lengthy computations, the main UI thread creates several worker threads. As the worker threads progress in the calculation, they report their progress to the main UI thread, which then displays progress.
这适用于共享内存中的数字进度值(由工作人员编写,由 UI 读取),但我在处理文本进度消息时遇到问题.我尝试的解决方案经过了多次迭代,但似乎都没有奏效.
This works fine for numeric progress values, which are in shared memory (written by workers, read by UI), but I'm having trouble with text progress messages. My attempted solutions have been through several iterations, and none seems to work.
我让 UI 线程将指向控件的指针传递给工作人员,工作人员直接更新了 UI.这不是很有效,而且似乎是错误的方法.
I had the UI thread pass pointers to controls to the workers, and the workers updated the UI directly. This wasn't very effective, and seems like the wrong approach.
我让工作人员使用 SendMessage 向 UI 线程的窗口发送消息.这就陷入了僵局.(在消息被处理之前,SendMessage 不会返回.)
I had the workers send messages, using SendMessage to the UI thread's window. This deadlocked. (SendMessage doesn't return until the message has been processed.)
与 (2) 相同,除了使用 PostMessage 到 UI 线程的窗口.这工作了一段时间,然后消息丢失了.(PostMessage 立即返回.)进一步调查显示消息队列的配额已超过默认值 10,000.
Same as (2), except using PostMessage to the UI thread's window. This worked, for a while, then messages got lost. (PostMessage returns immediately.) Further investigation revealed the quota for message queues, which defaults to 10,000, was being exceeded.
我增加了消息队列的配额(注册表中的变量 HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWindowsUSERPostMessageLimit),但丢失消息的数量没有改变.
I increased the quota for message queues (variable HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWindowsUSERPostMessageLimit in the registry), but the number of lost messages didn't change.
我让每个工作线程在 4 KB 缓冲区中缓冲消息,并在缓冲区填满时使用 PostMessage.这失败了,因为 UI 线程从未收到任何消息.当我将缓冲区大小增加到 64 KB 时也是如此.
I had each worker thread buffer messages in 4 KByte buffers, and PostMessage when a buffer filled. This failed because the UI thread never received any messages. Same was true when I increased the buffer size to 64 KBytes.
工作线程以最低"优先级运行,而 UI 线程以正常"优先级运行.工作线程正在发送带有类似代码的消息
The worker threads are running at "lowest" priority, and the UI thread at "normal" priority. Worker threads are sending messages with code like
UIMessage *pUI=new UIMessage; // so it won't go out of scope (main dialog will delete it)
pUI->buffer=traceLineBuffer; pUI->nOutputs=traceN;
BOOL ok=::PostMessage(hWndMainDlg,TraceLineMsg,(WPARAM)pUI, NULL/*lParam*/);
并且 UI 正在接收它们的代码,例如
and UI is receiving them with code like
BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
...
ON_MESSAGE(TraceLineMsg,OnTraceLineMsg)
...
END_MESSAGE_MAP()
LRESULT CMainDlg::OnTraceLineMsg(WPARAM wParam, LPARAM lParam)
{
UIMessage *pUI=(UIMessage *)wParam;
char *p=pUI->buffer;
// PROCESS BUFFER
delete[] pUI->buffer;
delete pUI;
return 0;
}
问题:
在可能会出现数千个文本报告的情况下,员工发布进度报告的首选方式是什么?
What is the preferred way for workers to issue progress reports, in a case where there may be bursts of several thousand text reports?
为什么不能增加队列中发帖的配额?
Why can I not increase the quota of post messages in a queue?
为什么主 UI 线程似乎从未收到缓冲区中的消息,即使传输它们的机制与发布单个报告相同?
Why does the main UI thread seemingly never receive the messages in the buffers, even though the mechanism for transmitting them was identical to posting the individual reports?
64 位 Windows 7、Visual Studio 2010、本机 C++/MFC
64-bit Windows 7, Visual Studio 2010, native C++/MFC
推荐答案
WaitForMultipleObjects 调用中的主线程不会处理任何消息,也不会更新控件或其他窗口.解决方案是:不要那样做.
With the main thread in a WaitForMultipleObjects call no messages will be processed and no controls or other windows can be updated. The solution is: Don't do that.
这篇关于工作线程如何与主 UI 线程通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:工作线程如何与主 UI 线程通信?
基础教程推荐
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01