As many of you may know, I write quite a lot about UI work and WPF technology, and I have in the past written articles about Threading, and have also written a great lot about my own WPF MVVM Framework Cinch, which includes a lot of stuff to get you up and running doing WPF the MVVM way.

Well, one thing that has always bugged me while working with WPF is threading and doing something in the background and keeping my UI nice and free to do other stuff. Sure I can spawn a new Thread or use the ThreadPool and even use the funky BackgroundTaskManager class inside of Cinch which does help a lot in terms of fetching data on an internally held BackgroundWorker and is completely unit testable, as discussed in this Cinch article. I just felt that more improvements could be made.

For example, what I would want to be able to do, is have a ViewModel (to allow Binding and testing) that was being used as a DataContext for some View, to be able to accept some parametised work delegate that would be performed on a background thread, and would show some busy animation or status while the threading operation was happening, and would then either show an error status in the View somewhere if the background threading operation failed, or would show me the actual data that the background thread fetched that I requested in the parametised work delegate, if there was no failure while fetching the relevant data.

I should point out that the code contained here does spawn a new BackgroundWorker per threading operation, where each operation is expected to return some single definable bit of data, such as a single List<SomeClass>, or even some other very expensive time consuming data to fetch. My intent was never to have some global threading manager that fetches all and sundry in one hit, it's more micro managing the data.

In laymen's terms, think of it like this (where "I" and "Me" in this italic paragraph means the demo app code provided in this article ):

You want me to show a List<Contact> that could take some time to fetch, fair enough. I'll create a BackgroundWorker to do that and manage that background activity, and let you know how it's going, and when I am done, I'll return you a List<Contact>, or some error message. Oh, and you also want me to show a List<BankAccount> on the same View that will also take some time to fetch. Well now, for that, I will need to return another type of List. In fact, it will be a List<BankAccount> so I am going to be needing another BackgroundWorker to do that, and return you your List<BankAccount>.

I know this could potentially spawn a few threads, but internally, the BackgroundWorker makes use of the ThreadPool, which is ace, so I do not feel it's an issue, as the management of Threads is done for us by the .NET Framework. Obviously, if you have hundreds of lists of data on one View, this article may not be for you at all, and you should stop reading right here. If on the other hand you have a few lists of data or a few expensive bits of data to fetch, this code could well be for you.

Anyway, that is how I see it working, and after messing around for a while, I think I have done just that.

There are a few assumptions that I have made, which are as follows:

That people are using WPF, and are pretty competent with it. This is not a beginner article at all.

That people are using the MVVM pattern.

That people think it's a good idea to have parts of your View show error messages if the data that was supposed to be fetched failed to happen.

That people are happy with the idea of an item of data (such as a List of data) or expensive bits of data being fetched by a dedicated BackgroundWorker manager object, which we will get to later.

The problem is really like this: from what I have seen, very few people take the time to show the user much feedback at the best of times, let alone when a long running threading operation is happening. In fact, some UIs just boldly do everything on the UI thread, and let the user wait. OK, some people do change the icon to an hour-glass or something, and disable buttons etc., while something is happening.

Wouldn't it be better if we had some component that kept the user in the loop? They start a long running operation either by requesting it or by opening up some View that requires it, and when that happens, the user is constantly shown what is going on as a progress bar is shown while we are doing the work, and if it fails, we show them why, right there in the UI, where it's visible, not in some MessageBox that disappears as soon as they accept "OK", and then try and ring support only to be asked what the MessageBox message said. Oh, I closed that, sorry. And of course, when it all goes to plan, simply hide the progress bar, do not show any failure UI, and just show them what they wanted that has now been fetched.

So what is the solution? Well, the solution is obviously to come up with something that fixes the problem, right?

Well, this article does fix all of the things mentioned above in the problem description. The way it does it, is by using various bits of WPF technology, and threading bits and pieces.

As I previously mentioned, the code supplied in the attached demo app is assuming that you are using the MVVM pattern. I am not saying you could not get it to work without using MVVM; it's just, I think MVVM is fab, and it works, and that is the only way I will be describing in this article's text.

The demo code makes use of a simple idea; we use a WPF UserControl to wrap a bit of content, which would be the UI data that you wish to fetch in a background thread.

So when it runs, it looks something like this:

The attached code makes use of the AdornerLayer to show different Adorners depending on the state of the background threading operation. If the background threading operation is busy, the BusyAdorner is shown. If the background threading operation failed and is not busy, the FailedAdorner is shown. If the background threading operation is not busy and not failed, hide both the BusyAdorner and FailedAdorner, which just leaves the original data shown in the UI, which has now been fetched on a background thread.

You can read more about how the Adorners work in the Adorners section below.

In this series of sub sections, I will outline how the attached demo code is structured. It should be noted that you will not need to know about a lot of this, you would simply include it in your project and do what is recommended in the How to Go About Using This Idea in Your Own WPF App section. But if you are like me, you will want to know about the details in full before knowing what you need to do to use it, so that is what this section is all about.

The demo app attached obviously has to demonstrate the total idea. As such, there is a retarded bit of code that allows the user to pick or choose whether the background threading operation should fail during runtime. The user is able to do this by clicking a button on the demo code's UI.

Now this is obviously only test code, and should never be used in production code; all it does is toggle a "ShouldFail" flag that is checked within the background thread delegate. Which is like this in the demo code:

Func<Dictionary<String, Object>,
ThreadableItem<List<StuffData>>> taskFunc = (inputParams) =>
{
try
{
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
#region TEST EXAMPLE CODE, YOU SHOULD NOT DO THIS IN PRODUCTION CODE
if (ShouldFail)
{
thrownew InvalidOperationException(
"InvalidOperationException occurred\r\n\r\n" +
"This Exception has been raised inside " +
"the Window1ViewModel delegate " +
"which is the actual payload for the " +
"ThreadableItemViewModel<T> TaskFunc delegate.\r\n\r\n" +
"Which is obvioulsy not what you would " +
"do in a production system.\r\n\r\n" +
"You would more typically catch your own business Exceptions " +
"(say from talking to WCF) and then rethrow them. " +
"This just demomstrated how all this hangs together");
}
else
{
List<StuffData> data = new List<StuffData>();
for (int i = 0; i < (Int32)inputParams["loopMax"]; i++)
{
data.Add(new StuffData(String.Format("The Text Is {0}",i),i));
Thread.Sleep(5); //simulate time going by
}
//work is done at this point, so return new ThreadableItem with the
//actual data in it, and no failure message
returnnew ThreadableItem<List<StuffData>>(data, String.Empty);
}
#endregion
}
//something went wrong so return a new ThreadableItem with the failed
//message in it
catch(Exception ex)
{
returnnew ThreadableItem<List<StuffData>>(null, ex.Message);
}
};

It is just there to demonstrate how the code is intended to work. In real production code, you would not do this; you would more likely do something like this:

While this may look a bit hairy right now, do not worry, we will be going through that rather nasty looking Func<T,TResult> delegate declaration a bit later. The important thing to note is that the demo code uses some gash test code that you should see as just that demo code that needs replacing with your real code, something like the code chunk seen above.

As I stated, the demo code uses the MVVM pattern. You might ask yourself why. The reasons are simple; MVVM allows us to bind directly to our ViewModel, and the ViewModel also serves as a very nice unit testing entry point. As such, there are various ViewModels in the attached demo code, the main ones being:

ViewModelBase: Simple INotifyPropertyChanged base class for all other ViewModels to inherit from.

ThreadableItemViewModelBase: This is a base class for ThreadableItemViewModel<T> based ViewModels, and allows the UserControl that handles the AdornerLayer and wraps the data to hook up INotifyPropertyChanged property changed watchers without having to care about the actual generic type of the current background threading operation. This class basically just exposes some common properties that all ThreadableItemViewModel<T> based ViewModels will need to use.

ThreadableItemViewModel<T>: This generic ViewModel inherits from ThreadableItemViewModelBase. Its job is to manage the background threading operation. As such, it has various properties that facilitate the management of the running of the background threading activity. The T generic should be the Type that you want for the background threading activity. So for example, if I expected to get a List<Client> back, T would beList<Client>
.

You would need to have one of these ThreadableItemViewModel<T> for each background activity you wish to perform. In the demo app, that is only one List of some imaginary Model data called "StuffData", so in my main ViewModel (Window1ViewModel), I have a single instance of ThreadableItemViewModel<List<StuffData>> which is used to manage the retrieval of aList<StuffData>
.

Here is what this looks like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;
namespace ThreadingComponent
{
///<summary>/// This ViewModel contains all the data required to run a work delegate
/// (the TaskFunc Func<Dictionary<String,Object>,ThreadableItem<T>>) and also
/// exposes methods to allow the work delegate to be run on a new thread. The
/// Data obtained by running the background thread is exposed on the Data
/// property, and the BgWorker is also exposed as a property so that it can be
/// used within Unit tests.
///</summary>///<typeparamname="T">The return type of the threading operation</typeparam>publicclass ThreadableItemViewModel<T> : ThreadableItemViewModelBase
{
#region Data
private ThreadableItem<T> data;
private Func<Dictionary<String,Object>,ThreadableItem<T>> taskFunc;
private BackgroundTaskManager<ThreadableItem<T>> bgWorker;
private Dictionary<String, Object> parameters = null;
#endregion
#region Private Methods
///<summary>/// Sets up the actual BackgroundTaskManager<T> component
///</summary>privatevoid SetupWorker()
{
if (taskFunc == null)
thrownew NullReferenceException("TaskFunc can not be null");
bgWorker = new BackgroundTaskManager<ThreadableItem<T>>(
() =>
{
return taskFunc(Parameters);
},
(result) =>
{
Data = result;
});
BgWorker.BackgroundTaskStarted -= BackgroundTaskStarted;
BgWorker.BackgroundTaskCompleted -= BackgroundTaskCompleted;
BgWorker.BackgroundTaskStarted += BackgroundTaskStarted;
BgWorker.BackgroundTaskCompleted += BackgroundTaskCompleted;
}
///<summary>/// Event that is raised when the background work is Completed. This event
/// is raised by the internal BackgroundTaskManager<T> component
///</summary>privatevoid BackgroundTaskCompleted(object sender, EventArgs args)
{
//The order that these properties IS IMPORTANT, as it dictates
//which Adorner will be shown
IsBusy = false;
Failed = !String.IsNullOrEmpty(Data.Error);
}
///<summary>/// Event that is raised when the background work is Started. This event
/// is raised by the internal BackgroundTaskManager<T> component
///</summary>privatevoid BackgroundTaskStarted(object sender, EventArgs args)
{
//The order that these properties IS IMPORTANT, as it dictates
//which Adorner will be shown
IsBusy = true;
Failed = false;
}
#endregion
#region Public Methods
///<summary>/// Run the work delegate on a new thread
///</summary>publicvoid Run()
{
SetupWorker();
bgWorker.RunBackgroundTask();
}
#endregion
#region Public Properties
///<summary>/// The actual work delegate. This must ALWAYS take a
/// Dictionary<String,Object> as the 1st parameter, which is the collection
/// of parameters that the work delegate may need to do its work. This can obviously
/// be null. The T is the expected return type for the threading operation
///</summary>public Func<Dictionary<String,Object>,ThreadableItem<T>> TaskFunc
{
set
{
taskFunc = value;
}
}
///<summary>/// A Dictionary of key/value pairs, where each pair is a parameter
/// that the work delegate (TaskFunc) may need to do its work
///</summary>public Dictionary<String, Object> Parameters
{
get { return parameters; }
set { parameters = value; }
}
///<summary>/// The BackgroundTaskManager exposed so you can use it within
/// Unit tests. See the actual <seecref="BackgroundTaskManager">/// BackgroundTaskManager</see> code for how to do that
///</summary>public BackgroundTaskManager<ThreadableItem<T>> BgWorker
{
get { return bgWorker; }
}
///<summary>/// The actual Data that is the result of running the
/// background threading operation
///</summary>public ThreadableItem<T> Data
{
get { return data; }
set
{
data = value;
if (data != null)
this.ErrorMessage = data.Error;
NotifyPropertyChanged("Data");
}
}
#endregion
}
}

The most important things to note in this bad boy are the public properties:

TaskFunc: Which is a Func delegate that is the actual background work you want done.

Parameters: ADictionary<String,Object>
which is fed into the TaskFunc, Func delegate which is your parameters collection, which may be useful when running the background operation.

BgWorker: The actual BackgroundTaskManager<T> which is exposed to allow a Unit Test to maybe set up a AutoResetEvent and only Wait a specific amount of time for the operation to happen, before assuming it failed. The BackgroundTaskManager<T> class is straight out of my Cinch MVVM framework, and is discussed in this Cinch article.

Data: Is the actual data which is of Type ThreadableItem<T>, so what does one of those look like then? Well, ThreadableItem<T> is a simple class that represents the result of the background operation, so it has a DataObject and an Error. Only one of which is expected to be an actual value at any one time.

If the operation ran successfully, then the ThreadableItem<T>'s DataObject will be an instance of T that the user asked for, and the ThreadableItem<T>'s Error will be an empty string.

If the operation failed, the ThreadableItem<T>'s DataObject will be null, and the ThreadableItem<T>Error will be an Exception message string.

So far, all we have covered in the ViewModels, you will most likely not change, so there is one more to cover which is how to actually use the ones we have seen above. In the demo app, there is a single Window called Window1.xaml, this has a single ViewModel (to allow binding) called Window1ViewModel, which manages all the operations that Window1 wants to do.

Window1ViewModel is an exemple of how to use the rest of the codebase, though as I previously stated, does have test code in it so you can see how all this fits together, and you will need to change it in your production code. Again, I showed you an example of that earlier.

Whilst not strictly part of the article's main thrust, I would recommend using some sort of DelegateCommand, or Josh SmithRelayCommand, or Marlon GrechSimpleCommand (which is what I use), all of which allow your UI to bind to a ViewModel exposed ICommand and actually run code in the ViewModel. The reason I would recommend ICommands is that you can disable a button in the ICommand.CanExecute directly in the ViewModel if there is a background threading operation in progress. For an example of this, see Window1ViewModel.

Obviously, this only applies if the threading operation happens as a result of a button click or something the user initiated.

Since this article is all about a background threading component/idea, you would expect there to be loads to say about Threads. Well, actually a lot of that is abstracted from you.

The steps involved are pretty much like this (you can use the attached demo Window1ViewModel code as a basis for writing your own ViewModel code to use this article's ideas/concepts).

Step 1: Expose property and pick T

Create a ViewModel, and expose a ThreadableItemViewModel<T> as a public property which you can then bind to using a ThreadableHostControlUserControl which is described in the next section, where the generic T must obviously be qualified with the correct type; for example, here is a valid property declaration:

Step 2: Wire up background work delegate

Now that you have exposed ThreadableItemViewModel<T> as a public property, and picked a return type for it, we can look at how to get the results in a background thread. This is easily achieved; all we have to do is set up the background work delegate, which is done as follows:

Func<Dictionary<String, Object>, ThreadableItem<List<StuffData>>> taskFunc = (inputParams) =>
{
try
{
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
// REGION BELOW FOR TESTING ONLY
#region TEST EXAMPLE CODE, YOU SHOULD NOT DO THIS IN PRODUCTION CODE
if (ShouldFail)
{
thrownew InvalidOperationException(
"InvalidOperationException occurred\r\n\r\n" +
"This Exception has been raised inside the Window1ViewModel delegate " +
"which is the actual payload for the " +
"ThreadableItemViewModel<T> TaskFunc delegate.\r\n\r\n" +
"Which is obvioulsy not what you would do in a production system.\r\n\r\n" +
"You would more typically catch your own business Exceptions " +
"(say from talking to WCF) and then rethrow them. " +
"This just demomstrated how all this hangs together");
}
else
{
List<StuffData> data = new List<StuffData>();
for (int i = 0; i < (Int32)inputParams["loopMax"]; i++)
{
data.Add(new StuffData(String.Format("The Text Is {0}",i),i));
Thread.Sleep(5); //simulate time going by
}
//work is done at this point, so return new ThreadableItem with the
//actual data in it, and no failure message
returnnew ThreadableItem<List<StuffData>>(data, String.Empty);
}
#endregion
}
//something went wrong so return a new ThreadableItem with the failed
//message in it
catch(Exception ex)
{
returnnew ThreadableItem<List<StuffData>>(null, ex.Message);
}
};
//setup Threading task function
threadVM.TaskFunc = taskFunc;

The important thing to observe here are that we return a ThreadableItem<T> where T is of type List<StuffData>. And remember, a Func<T,TResult> is nothing more than a delegate that looks like this:

publicdelegate TResult Func<T, TResult>(T arg);

So really, all we are just saying is that we have a delegate that takes Dictionary<String, Object> as an input parameter, and it returns ThreadableItem<List<StuffData>> as a return value. Simple, right?

The Dictionary<String, Object> acts as a collection of parameters that may be needed by the thread work item, so we need to configure it like so:

This code makes use of a funky BackgroundTaskManager class inside of Cinch which does help a lot in terms of fetching data on an internally held BackgroundWorker and is completely unit testable, as discussed in this Cinch article. The important thing to note here is to see how this simply calls the original taskFunc property, which is the one that you just specified using the Func<T,TResult> delegate, remember?

It also passes the Func<T,TResult> delegate the parameters Dictionary<String, Object>, which are the parameters that can be used inside the threading delegate work item.

I guess I better prove this all works with a screenshot. Here is a screenshot using the worker item code above:

Word of warning

The code above is just there to demonstrate how the failure code is intended to work. A reader alerted me to the fact that the previous article (yes, this is being posted again) took up 400MB of RAM. Now, the reason that was is my old worker delegate used to create 5,000,000 objects in memory, which as you can imagine was a real issue. Now, we would never actually do that in a production environment. I have modified the code to use a much more modest 30000 objects, which uses like 19MB of RAM. So thanks to that user for spotting that. I am glad it was not something stupid I had done. Phew.

In fact, after I published it again, the same user Insomniac Geek came up with another rather sensible suggestion, which is to use a few items (1000) and use a System.Threading.Thread.Sleep(5) to simulate some work, so that is what I do now. As even with 30,000 items, the background thread happened in milliseconds. So thanks user Insomniac Geek.

In real production code, you would not do this, you would more likely do something like this:

Now that you know there is a ThreadableItemViewModel<T> property exposed that makes use of an internal ThreadableItem<T>, we can imagine making use of that in the UI. This is done via exposing a ThreadableItemViewModel<T> property in your own ViewModel, like this:

It can be seen that there is a ThreadableHostControlUserControl which makes use of thisThreadableItemViewModel<List<StuffData>> ThreadVM
property exposed by the ViewModel.

There are two clever things going on here:

Let Content Be Content

In WPF, there are loads of different ways to do things, but I always like to keep my XAML as clean as I can. Part of the trick is understanding the framework, but also knowing what classes support what properties. A UserControl has a Content property, so let's just use that to host the data that we want to show which is fetched in the background thread. In this case, this will be a List<StuffData> bound to a ListView.

We could have done some tricks with several UI controls having their Visibility properties toggled, but that means more XAML, ouch. A better way is to let the content be content, and then we can host extra content on top of the content in a layer called the AdornerLayer.

Supporting Adorners

The ThreadableHostControl.ThreadableItem property is bound to an instance of ThreadableItemViewModel<T> which inherits from ThreadableItemViewModelBase, which as I mentioned earlier was the base class for all ThreadableItemViewModel<T> that supported a couple of properties namely:

IsBusy

Failed

ErrorMessage

So how does the ThreadableHostControlUserControl make use of the ThreadableItemViewModelBase property that it gets via a Binding? Well, that is quite interesting; let's have a look, shall we?

If we follow one of these through, say the Failed -> FailedChanged() method, we will see what happens:

///<summary>/// Shows the FailedAdorner
///</summary>privatevoid FailedChanged(ThreadableItemViewModelBase vm)
{
if (vm.IsBusy)
return;
//If the users chose to throw an Exception on a null AdornerLayer
//throw an Exception. The user may change this setting in the App.Config
//which obviously impacts how the code works, but the Background
//thread will still run, its just that the Adorners that this class
//manages will not be shown. Which is not how the code was intended
//to work. It would be better to find out why the AdornerLayer is null
adornerLayer = AdornerLayer.GetAdornerLayer(this);
if (shouldThrowExceptionOnNullAdornerLayer && adornerLayer == null)
thrownew NotSupportedException(
"The ThreadableHostControl will only work correctly\r\n" +
"if there is an AdornerLayer found and it is not null");
if (adornerLayer != null)
{
if (vm.Failed)
{
SafeRemoveAll(new List<CustomAdornerBase>() { failedAdorner, busyAdorner });
failedAdorner = new FailedAdorner(this, vm.ErrorMessage);
adornerLayer.Add(failedAdorner);
}
else
{
SafeRemoveAll(new List<CustomAdornerBase>() { failedAdorner, busyAdorner });
}
}
//repaint
InvalidateControl();
}

See how this method is used to show a FailedAdorner in the AdornerLayer (if it's found and not null). The last piece of the puzzle is to see what the actual FailedAdorner looks like. Well, it's dead simple (there is a CustomAdornerBase base class, but I'll spare you that); it looks like this:

It can be seen that the FailedUserControl uses the ErrorMessage property to display the error that occurred with the threading operation. This ErrorMessage property DP on the FailedUserControl was set on the FailedUserControl by the FailedAdorner in response to the actual ThreadableItemViewModelBase.Failed property changing.

As I have stated in various places in the article, the attached demo code's ThreadableHostControlUserControl uses the AdornerLayer, which can occasionally come back as null (say, if you are using your own AdornerDecorator, or are in the middle of some crazy control such as an Infragistics one or a fat Ribbon), and as such, the attached demo code's ThreadableHostControlUserControl would not really work as planned.

To deal with this, the user can choose how this can be handled by using the App.Config setting "shouldThrowExceptionOnNullAdornerLayer" which directs the app to throw an Exception if the AdornerLayer can not be obtained.

If the user chooses to set the "shouldThrowExceptionOnNullAdornerLayer" App.Config value to "false", the threading should all work as expected; it is just the busy or failed Adorners that will not be shown, and the user will have to work out another way of dealing with the IsBusy and Failed states of the background threading operation.

Obviously, it would be better for everyone if this setting remains set to "true" and the user finds out why the AdornerLayer.GetAdornerLayer(this) is returning null.

That is all I wanted to say right now. I have to say, for me, this was a real problem on a large scale WPF app, and this code will solve very real issues we have on that project. If you too feel that this could be useful in your WPF app, could you spare the time to make a comment or a vote? Many thanks.

Comments and Discussions

Thanks for an excellent article. I actually solved this problem a little while ago. I wanted to show everyone this alternate solution. If you have time, please provide feedback.

As the subject suggests, I created an AsyncRelayCommand instead of creating a ThreadableItemViewModelBase like you did. Rest of the logic is pretty much the same. Each AsyncRelayCommand has a backgroundworker in it.

I do not get this, where is toExecute() method shown above, should that not be your Action<object> input parameter to AsyncRelayCommand, and also this is WPF, and I guess you are using AsyncRelayCommand to do nice MVVM apps right?

So doesn't having a Window right there in the command kind of break MVVM, and Unit Testability for that matter? How do you UnitTest that?

Sacha Barber

Microsoft Visual C# MVP 2008/2009

Codeproject MVP 2008/2009

Your best friend is you.I'm my best friend too. We share the same views, and hardly ever argue

toExecute is the Action<object> input parameter. My AsyncRelayCommand inherits from RelayCommand which is a bare bones implementation of ICommand.

The constructor public AsyncRelayCommand(Action<object> execute) : base(execute) calls the base which assigns toExecute that is given by the viewmodel.

As for your other comment about the ProgressWindow, you are right. I did not think about putting a view in this command. When an AsycnRelayCommand is executing, I need to disable the view with a progress window. What would you suggest for something like this?

What we tend to do is use IOC to inject either a real IProgressWindow, or some Mock IProgressWindow, which can be used it testing.

So the IProgressWindow may look like

publicinterface IProgressWindow
{
Show()
Hide();
}

And since you already have a Window that implements these, you can just have a Window that inherits from IProgressWindow, and inject that in your real code. Then for your tests, have a dummy IProgressWindow type that would be something like