How can I update my user interface from a thread that did not create it?

When performing any action on a control which requires the updating of a user interface element (e.g. setting the Text property on almost any class derived from Control, updating the data source behind a DataGrid), these operations MUST take place on the thread that created the UI element.


In order to do this, the Control class provides the Invoke method, which will take a delegate and execute it on the thread that the UI element was created on. In order to use this, one must declare a function that performs the UI operation. For example, say a form has a TextBox on it named m_TextBox. To update the text from another thread, create a method that will update the Text property on the TextBox:

// The declaration of the textbox.
private TextBox m_TextBox;

// Updates the textbox text.
private void UpdateText(string text)
{
// Set the textbox text.
m_TextBox.Text = text;
}


Now, create a delegate that has the same signature as the method that was previously defined:

public delegate void UpdateTextCallback(string text);

In your thread, you can call the Invoke method on m_TextBox, passing the delegate to call, as well as the parameters.

m_TextBox.Invoke(new UpdateTextCallback(this.UpdateText), 
new object[]{”Text generated on non-UI thread.”});

Note: Do not create a method that matches the EventHandler delegate signature and pass that. The implementation of Invoke on the Control class will not take into account the parameters passed to Invoke if the type of the delegate is EventHandler. It will pass the control that Invoke was called on for the sender parameter as well as the value returned by EventArgs.Empty for the e parameter.


[Author: Nicholas Paldino]