CSingleLock Lock()后MFC应用程序挂起

时间:2015-05-13 05:00:37

标签: c++ multithreading visual-c++ mfc

void CADAPBatchView::AddMsgToStatusWindow(const CString& strMsg)
{
    CString strTemp;
    CString strEngineStatusEntry;
    int nLinesToScrollPast = 0;
    int nTrimPos = 0;
    strEngineStatusEntry.Format(_T("%s %s\n"), CTime::GetCurrentTime().Format( _T( "%H:%M:%S" )), strMsg);

    CSingleLock singleLock( &m_csStatusMsg );
    singleLock.Lock();

    if (m_wndEngineStatusMsgs.GetLineCount() > 200)
    {
        m_wndEngineStatusMsgs.SetReadOnly(FALSE);   //remove readonly so SetSel will work
        m_wndEngineStatusMsgs.SetSel(0, m_wndEngineStatusMsgs.LineIndex(100));
        m_wndEngineStatusMsgs.Clear();
        m_wndEngineStatusMsgs.SetReadOnly(TRUE);    //put back readonly
    }

    int nBegin;
    nBegin = m_wndEngineStatusMsgs.GetTextLength();
    m_wndEngineStatusMsgs.SetSel(nBegin, nBegin);   // Select last character
    m_wndEngineStatusMsgs.ReplaceSel(strEngineStatusEntry);          // Append, move cursor to end of text
    //m_wndEngineStatusMsgs.SetSel(-1,0);             // Remove Black selection bars
    //nBegin = m_wndEngineStatusMsgs.GetTextLength(); // Get New Length
    //m_wndEngineStatusMsgs.SetSel(nBegin,nBegin);    // Cursor to End of new text

    nLinesToScrollPast = m_wndEngineStatusMsgs.GetLineCount() - 9 - m_wndEngineStatusMsgs.GetFirstVisibleLine();
    m_wndEngineStatusMsgs.LineScroll( nLinesToScrollPast );


    if (m_wndChkStatusMsgLog.GetCheck() == 1)
    {
        WriteToLogFile(strEngineStatusEntry);
    }

    return;
}

我附上了显示两个主题的代码。在转储文件发生崩溃时,我看到主线程位于singlelock.Lock()之后的行。第二个线程位于以nLinesToScrollPast开头的行。我认为发生了僵局,但不知道如何。感谢任何帮助。谢谢。

1 个答案:

答案 0 :(得分:2)

问题是你试图使方法AddMsToStatusWindow线程安全,以便从其他线程调用它。您的问题是只允许主应用程序线程与GUI交互,否则您最终会遇到消息泵问题(因为您确实锁定了SendMessage)。所以你的设计是错误的。您应该基于CCriticalSection创建受保护的消息队列。因此,线程会将消息放入队列,然后调用PostMessage以通知主线程已将数据/消息放入队列。主线程将在消息处理程序中填充此队列中的数据。