As many of you 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 in, 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 1 hit, it's more micro managing the data.
In layman'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 of List<BankAccount> so I am going to be needing another BackgroundWorker to do that, and return you your list of 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 100rds 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).
If you want to know more about how all this works, you can read the full article and grab the source code from there:
http://www.codeproject.com/KB/WPF/ThreadingComponent.aspx