Updating UI on another Thread / Delegate

C

Code Monkey

Suppose I have a windows form (.exe) that has a load of labels and
text boxes on it.

I enter a number into one of the text boxes and hit the search button.

This then launches another thread, which may or may not spawn other
threads.

What's the best way of updating the user interface?

BackgroundWorker?


or calling something like

SetText("something", myControl);

for each control that I want to set the text for?

Bearing in mind that we're updating the user interface on a different
thread than what it was started on.


<code>
private delegate void SetTextCallback(string text, Control
controlName);
private void SetText(string text, Control controlName)
{
if (controlName.InvokeRequired)
{
SetTextCallback d = SetText;
Invoke(d, new object[] {text, controlName});
}
else
{
controlName.Text = text;
}
}
</code>
 
P

Peter Duniho

Suppose I have a windows form (.exe) that has a load of labels and
text boxes on it.

I enter a number into one of the text boxes and hit the search button.

This then launches another thread, which may or may not spawn other
threads.

What's the best way of updating the user interface?

BackgroundWorker?

or calling something like

SetText("something", myControl);

for each control that I want to set the text for?

If BackgroundWorker is sufficient for your needs, I highly recommend it.
It provides a very nice, clean, simple interface for dealing with the
cross-thread issues (assuming you only ever update your UI in the
ProgressChanged or RunWorkerCompleted events).

I will note that the pattern used in the method you posted is, IMHO,
unnecessarily verbose and complicated. It's not harmful to use
Control.Invoke() even if you're already executing on the correct thread.
And more than likely, you already know you're on the wrong thread anyway..
Also, you don't need a separate delegate variable for the call to
Invoke(), even when using a named method. And if you use an anonymous
method, even better.

So, for example, instead of all the rigamarole you posted (no offense
intended...I realize that what you posted is basically the boilerplate
pattern that MSDN recommends), you could do this:

myControl.Invoke((MethodInvoker) delegate { myControl.Text = text; });

You can, of course, wrap that up in a method to make it even simpler:

private void SetText(string text, Control controlName)
{
controlName.Invoke((MethodInvoker) delegate { controlName.Text =
text; });
}

In neither case do you really need all that others stuff.

But, if you can use BackgroundWorker instead, even better. :)

Note: by this I do not mean that you'd use BackgroundWorker _just_ to
update the GUI. It would only make sense to use BackgroundWorker if the
task that you're already putting in another thread can suitable be put as
the DoWork event handler for a BackgroundWorker instead.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top