winapi - 如果主 UI 线程处于睡眠状态或未处于活动状态,如何检查 Worker 线程内部
问题描述
我创建了一个带有 OutputPanes 的 Visual Studio 2019 应用程序,用于查看来自 WorkerThread 的跟踪日志。
在 WorkerThread 中,我填写了一个CStringList mStrDebugList
如果发生了一些有用的信息,并通知主 UI 以PostMessage
立即阅读和显示。
//////////////////////////////////////////////////////////////////////////
// TRACE Debug messsages for this App wide
void TRACE_DEBUG(LPCTSTR pszstring)
{
TRACE(pszstring);
CTestApp* pApp = (CTestApp*)AfxGetApp();
if (pApp)
{
TAutoLock lock(res);
theApp.mStrDebugList.AddTail(pszstring);
}
这可行,但如果应用程序已最小化或不在前台,则在数小时后CStringList
包含太多元素(> 20k)并且主 UI 无响应(~5Min),直到在 UI 中读取和删除所有元素。
void COutputWnd::FillInfoWindow()
{
TestApp* pApp = (CTestApp*)AfxGetApp();
if (pApp)
{
TAutoLock lock(res);
CString str;
while (!theApp.mStrDebugList.IsEmpty ())
{
str.Format(_T("%5d %s"),nCounter, theApp.mStrDebugList.GetHead ());
m_wndOutputDebug.AddString (str);
theApp.mStrDebugList.RemoveHead ();
}
// Scroll to the end of Listbox
int nCount = m_wndOutputDebug.GetCount();
m_wndOutputDebug.SetTopIndex(nCount-1);
}
}
我的问题是,如果 UI 未处于活动状态(休眠),我如何检查 WorkerThread 内部,以防止填充CStringList
太多元素?
解决方案
我认为你的方法是错误的。如果 UI(主)线程处于“休眠”状态,您会做什么?阻止工作线程工作,即暂停它?它会不再收集数据吗?当 UI 再次被带到前台时会发生什么?工作线程必须一次性收集所有数据,这些数据仍然需要添加到调试窗口中,因此总响应时间会更长。
如果将数据添加到调试窗口(我猜是列表框派生类)需要很长时间,那么没有真正的解决方案,无论如何都需要添加它们。只有一些优化:
m_wndOutputDebug.SetRedraw(FALSE);
在添加字符串之前调用m_wndOutputDebug.SetRedraw(TRUE);
,m_wndOutputDebug.Invalidate();
完成后,延迟可能是由于 UI 在添加每个项目后立即尝试绘制调试窗口造成的。- 避免那些
GetHead()/RemoveHead()
浏览列表的调用(这是开销,因为它可能会重新排列/重新分配列表),而是RemoveAll()
在完成时调用,这没有问题,因为您锁定了操作。
附注(与性能无关),为什么需要调用AfxGetApp()
?pApp
无论如何,您没有对它做任何事情 ( )。而且您有theApp
可用的单例(AfxGetApp()
应该只返回 的地址theApp
,不是吗?)。
推荐阅读
- javascript - django中的ajax请求后模板问题
- java - NetBeans (maven) 项目:checkstyle-beans vs maven-checkstyle-plugin
- ms-access - 如何从 ms-access 超链接字段中删除“#”符号?
- excel - VBA在应用Vlook up和公式时需要很长时间
- c# - 如何在 azure webjob 3.x sdk 中的触发方法中获取配置值
- javascript - 使用 Vue 和 AXIOS 从 API 循环构建数组
- python - 如何从模型 A 的 CreateView 重定向到模型 B 的另一个 CreateView,同时将关键信息从模型 A 传递到下一个视图?
- flutter - 如何在 DART 中的两个字符串之间获取子字符串?
- google-maps - 如何使用电容器在 Ionic 应用程序中为 Geolocation.watchPosition 设置超时
- java - Java FX 错误:“应用程序启动方法中的异常”