Skip to main content

Updating Controls from Non-GUI Thread

Here are a couple methods for how to update form controls from a non-GUI thread.

Explicit Setter Method

The following is an example method that can be called by non-GUI thread.

It first checks if running on the GUI thread.

If not, it will invoke a delegate (onto the GUI thread) that calls the same method.

If on the GUI thread, execution drops to the method bottom that does the update, on the GUI thread.

private void Append_Update_Status(string msg)
{
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate
        {
            Append_Update_Status(msg);
        });

        return;
    }

    this.txtUpdateStatus.Text = this.txtUpdateStatus.Text + msg + "" + "\r\n";
}

Generic Property Helper

Here's a helper class that you can leverage, to update any Control property from a non-GUI thread.

It will perform the Invoke work for you.

private delegate void SetControlPropertyThreadSafeDelegate(Control control,
                                                            string propertyName,
                                                            object propertyValue);

public static void SetControlPropertyThreadSafe(Control control,
                                                string propertyName,
                                                object propertyValue)
{
    // See if we are not on the GUI thread.
    if (control.InvokeRequired)
    {
        // Passa message to the GUI thread to update the control.
        control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe),
                        new object[] { control, propertyName, propertyValue });
    }
    else
    {
        // We are on the GUI thread.

        // Update the control.
        control.GetType().InvokeMember(propertyName,
                                        System.Reflection.BindingFlags.SetProperty,
                                        null,
                                        control,
                                        new object[] { propertyValue });
    }
}

You can call it, like this:

static public void Update_Form_Status(string msg)
{
  FormHelpers.SetControlPropertyThreadSafe(formcontrol, nameof(Control.PropertyName), msg);
}