从ui-thread显示窗口有时会阻塞主ui-thread
Displaying window from ui-thread sometimes blocks the main ui-thread
我不是一个MFC专家,绝对不是一个多线程专家,但仍然,我想了解这种奇怪的行为。在某些地方,当我在我的应用程序中创建一个MFC ui线程时,它启动并可以显示一个消息框,没有问题,主ui线程被阻塞。然而,有时如果我创建了一个线程,那么线程的执行就会停止,直到主ui线程再次被阻塞。
当然情况是编造的。主ui线程的阻塞,象征着某种同步,而ui线程的消息框象征着一些更复杂的ui对话框。
这更像是一个理论问题。我主要感兴趣的是为什么会发生这种情况?下面是一个例子:
class MessageBoxThread : public CWinThread
{
DECLARE_DYNCREATE( MessageBoxThread );
public:
virtual BOOL InitInstance()
{
CWinThread::InitInstance();
AfxMessageBox(_T("Some text"));
return TRUE;
}
};
IMPLEMENT_DYNCREATE( MessageBoxThread , CWinThread );
void testing()
{
MessageBoxThread* pMessageBoxThread = new MessageBoxThread ();
pMessageBoxThread->CreateThread();
Sleep(10000);
AfxMessageBox(_T("It Worked!"));
}
所以在这个例子中,如果我把"测试"函数放入CWinApp::InitInstance中,它会按预期工作(首先显示"一些文本",然后在10秒后显示"它工作了!")。但是,如果我把它放到应用程序深处的一个随机位置,可能会发生两个消息框在10秒睡眠后同时出现的情况。是什么导致了这种行为?
我不是MFC粉丝,但知道Win32我可以看到发生了什么。说它"深",你可能是指在一些窗口消息处理代码中调用test()函数——这些代码运行在主UI线程上并处理泵送消息。你让UI线程进入睡眠状态在这个例子中类似于消息框或模态对话框所做的。所以,你的消息泵(在CWinApp中实现,我认为)被这个Sleep()阻塞,等待你完成处理响应你的代码执行的消息(不管什么消息)。
好了,我终于找到答案了。当某人创建ui线程时,此人必须初始化m_pmainnd成员,该成员包含ui线程基窗口。如果您没有这样做,框架将使用应用程序提供的主窗口,即主ui线程中的主窗口。由于Sleep()方法阻塞了那个ui线程,所以另一个ui线程只有在主线程未阻塞时才会响应。
相关文章:
- QThread::create running on UI Thread
- 如何从 bash 脚本捕获终端输出并将其显示在我的 Qt UI 中?
- 通过屏蔽 UI 中的所有其他控件,在 UWP 应用 (c++) 中的现有 MainPage.xaml 顶部显示进度条
- 一个人如何将QT(C )UI分为多个小部件子类,并使其显示与同一类中的所有窗口
- 无法从 void 函数内向 UI 显示 - QT
- 在 std::thread 中使用无限循环来递增和显示值
- QT子类UI表单显示一个空白窗口
- C++:如何在UI线程和worker std::thread之间使用std::condition_variable
- 如何使 UI 对象仅在单击按钮后显示在对话框中
- 如何在对话框编辑框中显示来自 UI 线程类 Run() 函数的字符串
- boost - thread.join() halts the ui
- QT在菜单项上显示模态对话框(.UI)单击
- 如何检测地铁 UI 是否显示
- 禁止显示警告"QApplication was not created in main() thread"
- 单击按钮时显示另一个 UI 文件
- 如何在同一个容器(C++)中显示来自不同应用程序的ui
- 在Lotus Notes/Domino中运行查询而不显示Notes UI
- 如何在Repeater内部的UI QML (QT)中显示列表中的值
- 从ui-thread显示窗口有时会阻塞主ui-thread
- Win8如何将进程分类为"Background Process"?我的应用在 Win7 中运行,但在 Win8 中不显示任何 UI