Update UI from background worker thread without explicit marshalling


It is possible to update the UI thread from a background worker thread without the need to explicitly marshal the call across to the UI thread. An example follows.

A separate blog entry details how to update a UI using explicit marshalling.

The background worker member is used to perform potentially long lasting non-UI activities:

    private BackgroundWorker m_bw = new BackgroundWorker();

When starting the background worker (e.g. in the instance constructor after InitializeComponents for a WPF application) set the flag to indicate that the worker reports progress and add a ProgressChangedEventHandler:

    m_bw.DoWork += bw_DoWork;
    m_bw.WorkerReportsProgress = true;
    m_bw.ProgressChanged += bw_ProgressChanged;
    m_bw.RunWorkerAsync();

In the background worker activity when you want to update the UI call the ProgressChanged method on the background worker using the overload to pass a state object:

    int progress = 50;
    var state = new KeyValuePair<string, string>("Status", "Still working");
    m_bw.ReportProgress(progress, state);

The event that this call raises is raised on the thread that created the background worker – so in this case the UI thread – which means that implicit marshalling has occurred. In the ReportProgressEventHandler you can then directly update the UI controls:

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ...

        var state = (KeyValuePair<string, string>) e.UserState;
        m_xamlProgress.Text = e.ProgressPercentage + "%";
        m_xamlStatus.Text = "Status: " + state.Value;

        ...
    }

This approach separates the creation of the update data from the activity of updating the controls – providing an implicit interface between the worker thread and the UI thread.

In more complex scenarios where threads that have not been created by the UI thread need to update controls the mechanism of Control.InvokeRequired followed by use of Invoke / Dispatcher can be used.

Advertisements

Spring clean your usings


If you have worked on software that has been extended, upgraded and re-factored over time – then you will be aware that using statements accumulate at the top of C# files.  Some of these will be for namespaces and types that are no longer used in the code below.

An addition to the Visual Studio 2008 IDE is the ability to clean up and organise these using statements.

Just right-click to get the context menu in your code files and you will see the new menu option “Organize Usings”.  With this you can remove usings that are no longer in use, or sort the usings for a more aesthetic list.  Or why not go for a full clean up and do both!