SyntaxHighlighter

Thursday, July 3, 2008

UI updates and threading

I've been working on a small Windows Forms app which has a thread running in the background. This read needs to send info back to the UI during certain intervals. It's a pretty easy problem to solve and there are numerous sources on the web explaining this.

I did come across weird behaviour when my app went into a deadlock. It hanged at the Invoke method in the following code:
// This updates some control safely
protected void UpdateSomeControl()
{
// Check if an Invoke is required
if (InvokeRequired)
{
// Update the UI through delegation
Invoke((ThreadStart)delegate()
{
// ... Update the UI ...
});
}
else
{
// ... Update the UI ...
}
}
This is upposed to work! So what happened?

Turns out there are two types of calls to modify a control in .Net. The first is a SendMessage and the other PostMessage. Invoke uses SendMessage, which causes the update message to be sent, but hangs around until the message has been processed. BeginInvoke uses PostMessage which is basically a fire-and-and-forget approach; the message is added to the queue and the process goes of doing other work without waiting for it to processed.

So my Invoke was obviously hanging around waiting for the control update to be completed, while the control update was waiting for some other process further back in the queue... at least that's how I understand it.

To solve this issue, simply use BeginInvoke rather than Invoke. I'm sure this fix is not appropriate for all problems, but in my case it did the trick.

For a more detailed explenation, see this CodeProject page.

No comments: