Pattern for Properly Updating a Control from Another Thread

If you've done any Windows programming with threads, you've probably run into the problem of modifing a control you've added to your Form from a thread you've started. The answer was to Marshal the data through a delegate from the Thread through the Invoke() method on the Form object (this.Invoke(delegate, object args[] )). This wasn't too bad, but I always found the code a bit messy and never really had a simple streamlined way of acomplishing this.

Yesterday I was doing something simple in a Form and 2005 was being, what seemed to me, extra picky about this. Aparently 2003 wasn't very strict and would let you get away with poorly threaded code.

Instead of punting and turning off the new cross threading checks (by setting CheckForIllegalCrossThreadCalls to false which is how 2003 functions), I did some reading. MS has a very simple slick pattern for handling both the Threaded call and the non-threaded call in one method.

In the following example, they demonstraite this pattern using a TextBox. The create a delegate and a method called SetText(string s) that you must always use when working with the textBox1 control:

public class Form1 : Form
private TextBox textBox1;
// ...
delegate void SetTextCallback(string text);

private void SetText(string text)
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
SetTextCallback d
= new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
this.textBox1.Text = text;
// ...

Notice how the SetText method adds itself as a delegate when an invoke is required. If an invoke is NOT required it just functions normally. Pretty cool, eh?

I was able to apply this pattern with accessing and modifling ListBox.Items colleciton as well and it worked flawlessly.

Here's the MS HOWTO article: How to: Make Thread-Safe Calls to Windows Forms Controls

kick it on


  1. I have been using this method for quite a while now, but out of interest I always use BeginInvoke which posts a message to the message queue asyncronosly where as Invoke waits for the delegate to return.

    Any reason you demostrated Invoke not BeginInvoke here?

  2. That's a good question. The main difference I see (at least right off, I'm no expert) is that BeginInvoke will return immediately and Invoke will block until the return happens.

    If I don't have a return value from the delegate, and the delegate I'm calling isn't doing anything CPU intensive, it's really a toss up between Invoke and BeginInvoke. In fact, you might as well call BeginInvoke in these situations.

    However, if the operation I'm performing isn't CPU intensive and I want a return value from my delegate, the Invoke is quick and simple, as it simply returns 'Object' - which is the return value from my delegate. If I use BeginInvoke and need a return value, there's a few more lines of code needed to deal with the IAsyncResult returned from BeginInvoke to get the return value from the delegate.

    See the blog post by Microsoft Guy Justin Rogers WinForms UI Thread Invokes for more discussion on this topic.

  3. Hi,
    same code is working in c# windows application, but it is not working in web application...even i am using begininvoke for a deligate.. please help me

  4. prabhakara,
    this only works on Windows Forms applications. There shouldn't be any need for this in an ASP.NET application.