Multithreaded UI problem

  • Thread starter Thread starter bisquic
  • Start date Start date
B

bisquic

Ok, I've read a handful of articles out there concerning the issue of
accessing a control from a thread other than the one from which it
was created. I think the most well-rounded solution I found is to
create a delegate to a function that accesses the control and then
call this->Invoke( theDelegate ) from the worker thread in the
form to marshal the call to the UI thread. I wrote a test app to try
this out and the problem I'm having is that if I try the following,
the function that should be called via Invoke never gets called, and
the code that follows the Invoke in ThreadLoop never gets
executed...

...
__delegate void DisableButtonDelegate();
DisableButtonDelegate* disableButton;
Button* aButton;
Thread* aThread;

View()
{
InitializeComponent();

disableButton = new DisableButtonDelegate( this, DisableButton
);

aThread = new Thread( new ThreadStart( this, ThreadLoop
));
aThread->IsBackground = true;
aThread->Start();
}

void ThreadLoop()
{
while ( true ) {
this->Invoke( disableButton );

MessageBox::Show( S"After invoke" );

aThread->Sleep( 2000 );
}
}

void DisableButton()
{
MessageBox::Show( S"Disabling button" );
aButton->Enabled = false;
}
...
However, if I place the aThread->Sleep BEFORE the Invoke, or if I
insert a MessageBox before the Invoke, everything works fine and
executes like I would expect it to. Can anybody with a deeper
understanding of what's happening explain this to me? Also, is there
a prefered way of dealing with this situation?
 
yep, that was the problem. It worked sometimes because there was a
race condition between Application::Run and the new thread. The
Sleep or MessageBoxes gave the window enough time to open before the
Invoke was called, but when they weren't there, the Invoke was called
first. Thanks for the info!
 
Back
Top