update the GUI from another thread in C#

Total Post:51

Points:359
ASP.Net  C# 
C#
 1515  View(s)
Ratings:
Rate this:
What is the simplest way to update a Label from another thread?

I have a Form on thread1, from that I'm starting another thread (thread2). While thread2 is processing some files I would like to update a Label on the Form with the current status of thread2's work.

How can I do that?
  1. Post:194

    Points:1396
    Re: update the GUI from another thread in C#

    For .NET 3.0 you should use this code.

    private delegate void SetPropertyThreadSafeDelegate<TResult>(Control @this, Expression<Func<TResult>> property, TResult value);
     
            public static void SetPropertyThreadSafe<TResult>(this Control @this, Expression<Func<TResult>> property, TResult value)
            {
                var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;
     
                if (propertyInfo == null ||
                    !@this.GetType().IsSubclassOf(propertyInfo.ReflectedType) ||
                    @this.GetType().GetProperty(propertyInfo.Name, propertyInfo.PropertyType) == null)
                {
                    throw new ArgumentException("The lambda expression 'property' must reference a valid property on this Control.");
                }
     
                if (@this.InvokeRequired)
                {
                    @this.Invoke(new SetPropertyThreadSafeDelegate<TResult>(SetPropertyThreadSafe), new object[] { @this, property, value });
                }
                else
                {
                    @this.GetType().InvokeMember(propertyInfo.Name, BindingFlags.SetProperty, null, @this, new object[] { value });
                }
            }

    which uses LINQ and lambda expressions to allow much cleaner, simpler and safer syntax:

    myLabel.SetPropertyThreadSafe(() => myLabel.Text, status);

    Not only is the property name now checked at compile time, the property's type is as well, so it's impossible to (for example) assign a string value to a boolean property, and hence cause a runtime exception.

    Unfortunately this doesn't stop anyone from doing stupid things such as passing in another Control's property and value, so the following will happily compile:

    myLabel.SetPropertyThreadSafe(() => aForm.ShowIcon, false);

    Hence I added the runtime checks to ensure that the passed-in property does actually belong to the Control that the method's being called on. Not perfect, but still a lot better than the .NET 2.0 version.

      Modified On Apr-05-2018 11:24:12 PM

Answer