从ui-thread显示窗口有时会阻塞主ui线程

时间:2014-05-06 17:23:59

标签: c++ multithreading mfc

我不是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秒睡眠后同时出现。什么可能导致这种行为?

2 个答案:

答案 0 :(得分:2)

我不是MFC粉丝,但知道Win32我可以看到发生了什么。把它放在深处"你可能意味着在一些窗口消息处理代码中调用testing()函数 - 一个在主UI线程上运行并处理泵送消息的代码。因此,您要将UI线程置于睡眠状态,在这种情况下,类似于消息框或模式对话框的作用。因此,您的消息泵(我认为在CWinApp中实现)被此Sleep()阻止,等待您完成处理消息以响应您的代码执行(无论什么消息)。

答案 1 :(得分:1)

好的,我终于找到了答案。当有人创建一个ui线程时,该人必须初始化包含ui线程基本窗口的m_pMainWnd成员。如果你没有这样做,框架将使用应用程序提供的主窗口,这是主ui线程中的一个。因为那个因Sleep()方法而被阻止,所以另一个ui线程只会在主线程未被阻塞时响应。