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
开头的行。我认为发生了僵局,但不知道如何。感谢任何帮助。谢谢。
答案 0 :(得分:2)
问题是你试图使方法AddMsToStatusWindow
线程安全,以便从其他线程调用它。您的问题是只允许主应用程序线程与GUI交互,否则您最终会遇到消息泵问题(因为您确实锁定了SendMessage
)。所以你的设计是错误的。您应该基于CCriticalSection
创建受保护的消息队列。因此,线程会将消息放入队列,然后调用PostMessage
以通知主线程已将数据/消息放入队列。主线程将在消息处理程序中填充此队列中的数据。