Re: why UI gets hangs
Joseph M. Newcomer wrote:
It's a nasty one. Shocked me the first time I hit it...
joe
On Sun, 23 Mar 2008 21:23:54 +0100, "Giovanni Dicanio" <giovanni.dicanio@invalid.com>
wrote:
"Joseph M. Newcomer" <newcomer@flounder.com> ha scritto nel messaggio
news:fqadu3poeb3hq6qrct5c82galu2crmumco@4ax.com...
See my earlier note on PostMessage queue saturation and you can see my
essay on the use of
I/O Completion Ports to avoid this problem.
Thanks Joe.
I was unaware of PostMessage queue saturation problem.
I'm curious. I posted an example of this a few days ago. Are my posts
not coming through?
Post:
***
I put a thread in a sample dialog to see if I could break it.
Thread object:
struct TS
{
CString strT;
CDialog* pDlg;
bool bTReady;
};
class CA_Dialog_AppDlg : public CDialog
{
TS ts;
....
};
I'm sharing a CString that is on the dialog stack. It should have been
on the heap.
UINT Thread( LPVOID pParam )
{
TS& strct= *static_cast<TS*>( pParam );
for( long i= 0; ; ++i )
{
//if( strct.bTReady )
{
strct.strT.Format( _T("Test This %d"), i );
::PostMessage( *strct.pDlg, ID_CHECK_THREAD, 0, 0 );
strct.bTReady= false;
}
//Sleep( 5 );
//for( long j= 0; j < 20000; ++j )
;
}
return false;
}
In init dialog:
ts.pDlg= this;
ts.bTReady= true;
pThread= AfxBeginThread( Thread, &ts, THREAD_PRIORITY_LOWEST, 0,
CREATE_SUSPENDED );
pThread->m_bAutoDelete= FALSE;
pThread->ResumeThread( );
and member:
LRESULT CA_Dialog_AppDlg::OnCheckThread( WPARAM, LPARAM )
{
SetWindowText( ts.strT );
ts.bTReady= true;
return false;
}
With the 'if( strct.bTReady )' in the thread commented the dialog is
swamped with messages and is dead. But it would not crash and the title
bar updates! I figured that I would catch CString with an invalid
pointer and I may have if I'd kept going. But that is the point,
bTReady is used to make sure the thread is not changing data while the
app is using it. It also makes sure the thread doesn't post more
messages than the app can handle.
I also didn't stop the thread when the app quit, I just deleted it. But
to do it right it takes another semaphore that absolutely tells the
thread to exit. That means in every:
while( ! strct.bTReady && ! strct.bKill )
::Sleep( 5 );
In the exit:
ts.bKill= true;
WaitForSingleObject( pThread->m_hThread, INFINITE );
delete pThread;
Best, Dan.
***
And, Best, Dan.