Using ISynchronizeInvoke to update your UI safely from another Thread.

Microsoft .NET

If you are still using .NET threads to do multi-threading in your applications (compared to the Task Parallel Library or something else), then it is often a mistake of developers on how they update their UI thread. First off, stay the heck away from CheckForIllegalCrossThreadCalls. If you want your application to have unpredictable behavior, throw intermittant exceptions, and have loads of problems then go right ahead. If you want to do things right, read on.

In the early days of .NET, it was common to implement the Invoke pattern which is actually more work than needed. Most if not all WinForms controls for example implement an interface called ISynchronizeInvoke. You can use this to easily update your controls safely from another thread, in a single line of code. Here is the implementation:

namespace YourApplication {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;

    /// <summary>
    /// Helper class that allows synchronized invoking to be performed in a single line of code.
    /// </summary>
    internal static class SynchronizedInvoke {
        /// <summary>
        /// Invokes the specified action on the thread that the specified sync object was created on.
        /// </summary>
        public static void Invoke(ISynchronizeInvoke sync, Action action) {
            if (!sync.InvokeRequired) {
                action();
            }
            else {
                object[] args = new object[] { };
                sync.Invoke(action, args);
            }
        }
    }
}

This is just a helper class I usually include in all my WinForms projects as SynchronizedInvoke.cs. But the call is very simple. Let's say you have a thread that runs a method called "ThreadWork" and you want to set the value of a progress bar you've named 'uxProgressBar' to 100 at the end of the method.

private void ThreadWork() {
    // Do some work on a thread
    SynchronizeInvoke.Invoke(uxProgressBar, () => uxProgressBar.Value = 100);
}

The key is the first parameter, also called the 'sync', is the object you want to invoke on, and the second is just an anonymous method (you can also specify an actual Action). There's really nothing more to it, but you should also give a read to the article I wrote on using the Task Parallel Library titled 'Writing thread-safe event handlers with the Task Parallel Library in .NET 4.0' which in my opinion is a better way to perform threaded operations and UI updates.

1 Comment

  1. Aasad

    Now we dont need to create a new thread ,just use this line in our code with controls we want to put on thread and it would do multithreading ?????
    like below

    SynchronizeInvoke.Invoke(fpspread, () => fpspread.datasource=dt);

Leave a Comment