简体   繁体   English

MFC UI线程中的进度栏​​被阻止

[英]Progress bar in MFC UI Thread is blocked

For a MFC project at work, I have to create a progress bar dialog (CProgressCtrl) in a separate UI thread (CWinThread). 对于正在工作的MFC项目,我必须在单独的UI线程(CWinThread)中创建进度栏对话框(CProgressCtrl)。 I took the example from the site http://adilevin.wordpress.com/2009/06/29/user-interface-threads-in-mfc/ . 我从网站http://adilevin.wordpress.com/2009/06/29/user-interface-threads-in-mfc/中获取了示例。 It works on its own. 它可以独立工作。 (Basically, it has two progress bars, one from the main gui thread, one created in a separate ui thread. The example demonstrated that computation performed in the main gui thread does not disturb the progress bar created in the ui thread) (基本上,它有两个进度条,一个来自主gui线程,一个在单独的ui线程中创建。该示例演示了在主gui线程中执行的计算不会干扰ui线程中创建的进度条)

But when I put the code in my application, the progress bar got stuck in the SetPos call to the CProgressCtrl. 但是,当我将代码放入应用程序中时,进度条卡在了对CProgressCtrl的SetPos调用中。 When I freeze the main thread (while it's running computation), i get the message from Visual Studio 当我冻结主线程(运行计算时)时,我从Visual Studio收到消息

The process appears to be deadlocked (or is not running any user-mode code). 该进程似乎已死锁(或未运行任何用户模式代码)。 All threads have been stopped. 所有线程均已停止。

so it seems like the UI-thread is waiting for something from main thread? 所以似乎UI线程正在等待主线程发出的信号? But I have no idea what it is waiting for. 但我不知道它在等待什么。 Here is the call stack of the ui-thread where it get stuck. 这是卡住的ui线程的调用堆栈。

user32.dll!GetPropW()  + 0x72 bytes 
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]    
user32.dll!SendMessageW()  + 0x4c bytes 
uxtheme.dll!DrawThemeParentBackgroundEx()  + 0x114 bytes    
comctl32.dll!GetEffectiveClientRect()  + 0x28f0 bytes   
comctl32.dll!GetEffectiveClientRect()  + 0x2916 bytes   
comctl32.dll!GetEffectiveClientRect()  + 0x2af3 bytes   
comctl32.dll!GetEffectiveClientRect()  + 0x2a25 bytes   
comctl32.dll!GetEffectiveClientRect()  + 0x2992 bytes   
user32.dll!gapfnScSendMessage()  + 0x270 bytes  
user32.dll!gapfnScSendMessage()  + 0x922 bytes  
user32.dll!FillRect()  + 0x110 bytes    
user32.dll!CallWindowProcA()  + 0x1b bytes  
mfc100d.dll!CWnd::DefWindowProcA(unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 1089 + 0x20 bytes    C++
mfc100d.dll!CWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0)  Line 2088 + 0x1c bytes C++
mfc100d.dll!AfxCallWndProc(CWnd * pWnd=0x08156d68, HWND__ * hWnd=0x00012452, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 257 + 0x1c bytes C++
mfc100d.dll!AfxWndProc(HWND__ * hWnd=0x00012452, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 420  C++
cv32.dll!AfxWndProcDllStatic(HWND__ * hWnd=0x00012452, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 54 + 0x15 bytes    C++
user32.dll!gapfnScSendMessage()  + 0x270 bytes  
user32.dll!GetDC()  + 0x52 bytes    
user32.dll!GetWindowLongW()  + 0x18a bytes  
user32.dll!GetDC()  + 0xab bytes    
ntdll.dll!KiUserCallbackDispatcher()  + 0x2e bytes  
comctl32.dll!GetEffectiveClientRect()  + 0x2660 bytes   
comctl32.dll!RegisterClassNameW()  + 0x37e bytes    
user32.dll!gapfnScSendMessage()  + 0x270 bytes  
user32.dll!gapfnScSendMessage()  + 0x922 bytes  
user32.dll!FillRect()  + 0x110 bytes    
user32.dll!CallWindowProcA()  + 0x1b bytes  
mfc100d.dll!CWnd::DefWindowProcA(unsigned int nMsg=1026, unsigned int wParam=65, long lParam=0)  Line 1089 + 0x20 bytes C++
mfc100d.dll!CWnd::WindowProc(unsigned int message=1026, unsigned int wParam=65, long lParam=0)  Line 2088 + 0x1c bytes  C++
mfc100d.dll!AfxCallWndProc(CWnd * pWnd=0x08156d68, HWND__ * hWnd=0x00012452, unsigned int nMsg=1026, unsigned int wParam=65, long lParam=0)  Line 257 + 0x1c bytes  C++
mfc100d.dll!AfxWndProc(HWND__ * hWnd=0x00012452, unsigned int nMsg=1026, unsigned int wParam=65, long lParam=0)  Line 420   C++
cv32.dll!AfxWndProcDllStatic(HWND__ * hWnd=0x00012452, unsigned int nMsg=1026, unsigned int wParam=65, long lParam=0)  Line 54 + 0x15 bytes C++
user32.dll!gapfnScSendMessage()  + 0x270 bytes  
user32.dll!gapfnScSendMessage()  + 0x922 bytes  
user32.dll!GetWindow()  + 0x21a bytes   
user32.dll!SendMessageA()  + 0x4c bytes 
mfc100d.dll!CProgressCtrl::SetPos(int nPos=65)  Line 363 + 0x46 bytes   C++
cv32.dll!CProgressCtrlWithTimer::OnTimer(unsigned int nIDEvent=1)  Line 1577    C++

Anyone has any clue on what is wrong? 有人对哪里出问题有任何线索吗?

When I run the sample application on its own, it doesn't make calls to uxtheme.dll because it is not being used in the sample. 当我独自运行示例应用程序时,它不会调用uxtheme.dll,因为示例中未使用它。 Could the last SendMessageW be the problem? 最后一个SendMessageW可能是问题吗?

SetPos implies a call to SendMessage which is a blocking call. SetPos意味着对SendMessage的调用是阻塞调用。 You must never call SendMessage across thread boundary as this is doomed to cause deadlocks. 您绝不能在线程边界上调用SendMessage ,因为它注定会导致死锁。

If you need to update the GUI running on the main thread, you must use PostMessage : 如果需要更新在主线程上运行的GUI,则必须使用PostMessage

PostMessage(hWndMain, UWM_MYMESSAGE, progress, 0);

And handle the message in the main-thread: 并在主线程中处理消息:

LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam)
{
   m_progress.SetPos((int)wParam);
   return 1;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM