[英]How to create a modeless dialog from a worker thread when main GUI thread is blocked?
[英]How to check inside the Worker thread if the Main UI Thread is sleeping or not active
我創建了一個帶有 OutputPanes 的 Visual Studio 2019 應用程序,用於查看來自 WorkerThread 的跟蹤日志。
在 WorkerThread 中,如果發生了一些有用的情況,我會填充一個CStringList mStrDebugList
,並使用PostMessage
通知主 UI 以立即讀取和顯示。
//////////////////////////////////////////////////////////////////////////
// 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 再次被帶到前台時會發生什么? 工作線程必須一次性收集所有數據,這些數據仍然需要添加到調試 window 中,因此總響應時間會更長。
如果將數據添加到調試 window (我猜是列表框派生類)需要很長時間,那么沒有真正的解決方案,無論如何都需要添加它們。 只有一些優化:
m_wndOutputDebug.SetRedraw(FALSE);
在添加字符串和m_wndOutputDebug.SetRedraw(TRUE);
和m_wndOutputDebug.Invalidate();
完成后,延遲可能是由於 UI 在添加每個項目后立即嘗試繪制調試 window 造成的。GetHead()/RemoveHead()
調用來瀏覽列表(這是開銷,因為它可能會重新排列/重新分配列表),而是在完成后調用RemoveAll()
,這沒有問題,因為您鎖定了操作。 附注(與性能無關),為什么需要調用AfxGetApp()
? 無論如何,您都沒有對它做任何事情( pApp
)。 而且您有可用的theApp
singleton ( AfxGetApp()
應該只返回theApp
的地址,不是嗎?)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.