UPDATE THE GUI FROM ANOTHER THREAD IN C#

Hugh Jackman

Total Post:52

Points:366
Posted by  Hugh Jackman
ASP.Net  C# 
C#
 1189  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. Kamlakar Singh

    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.

Answer

NEWSLETTER

Enter your email address here always to be updated. We promise not to spam!