工作线程与主UI线程通信的最佳方式是什么?
摘要:我的C++/MFC应用程序是基于对话框的。为了进行冗长的计算,主UI线程创建了几个工作线程。当工作线程在计算中进行时,它们会向主UI线程报告进度,然后主UI线程显示进度。
这对于共享内存中的数值进度值(由工作人员编写,通过UI读取)很好,但我在处理文本进度消息时遇到了问题。我尝试过的解决方案经历了几次迭代,但似乎没有一次有效。
工作线程以“最低”优先级运行,UI线程以“正常”优先级运行。工作线程用代码发送消息,如
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正在用代码接收它们,如
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;
}问题:
64位Windows 7,Visual 2010,本机C++/MFC
发布于 2013-10-03 00:05:56
使用WaitForMultipleObjects调用中的主线程,不会处理任何消息,也不会更新任何控件或其他窗口。解决办法是:不要那样做。
发布于 2016-08-31 19:52:37
Windows上的MFC工作线程有多个选项可与主线程通信。您有标准的线程信令和同步原语 (互斥、信号量、事件)、易于使用的PostMessage和更高性能的I/O完成港机制。
// syncronization
{
CSingleLock lock(&sharedCriticalSection,TRUE);
sharedList.push_back(msg);
}
// other thread(s) are blocked/pending or you send an event or message to signal
// messages
Data* data = new Data(payload);
PostMessage(hWnd, REGISTERED_MESSAGE, 0, (LPARAM)data);
// target window handles message and deletes data
// if it is not blocked or too slow and the queue overflows
// skipping lots of IO completion port boilerplate and showing the key methods
messagePort = CreateIoCompletionPort(...);
...
GetQueuedCompletionStatus(messagePort,...);
...
PostQueuedCompletionStatus(messagePort,...);如果阻塞或繁忙-等待线程完成,它们中的任何一个都不会完成任务或提高性能或响应能力。
对你的意见的评论:
对你的问题的回答:
发布于 2013-10-03 10:39:34
在GUI上发布进度报告没有多大意义,因为它们可以更快地被用户吸收。当其他线程中有大量活动时,通常使用GUI计时器轮询线程中的进度vars,因此每隔500‘s更新GUI控件一次。
这是计时器轮询实际上是有利的少数几次之一。您可以得到peridoc进度报告,而不会在GUI Windows消息队列中填充更新。例如,uTorrent客户机(其中有大量的网络活动)使用此方案--尝试更新每个网络协议单元上的GUI下载状态肯定会填充GUI。
你在(5)中的缓冲方案应该是有效的。我经常通过将对象指针加载到LPARAM或WPARAM,在工作线程中对它们进行新的处理,并在显示后在GUI中删除它们,从而将大型数据项传输到主GUI线程。您的(5)应该已经工作,并且至少减少了进度数据传输的开销。我只能假设显示的数据量仍然太大,因此GUI线程仍然无法跟上:
https://stackoverflow.com/questions/19144112
复制相似问题