Wednesday, April 24, 2013

Create MVVM Background Tasks with Progress Reporting

Introduction

This article explains how to execute background tasks in a WPF application, complete with progress reporting. The techniques explained below can be applied to any time-consuming task that involves repetitive processing of items in a list. For example, one might need to perform the same processing on each file in a specified folder, or print a lengthy collection of documents.

There aren't many articles available that explain background and parallel processing in the context of an MVVM application, and that's what this article is intended to do. The background and parallel processing is based on the Task Parallel Library (TPL) introduced with .NET 4.0, which greatly simplified both types of processing in .NET applications.

The demo app for this article is built around the MVVM pattern, and the article demonstrates my approach to structuring MVVM apps, including the use of command and service classes. If you aren't familiar with MVVM, or if my implementation of MVVM isn't familiar to you, I recommend reading MVVM and the WPF DataGrid, which discusses my general approach in more detail.

Background

Like a lot of people, I avoided .NET background processing as long as I could. It seemed difficult and arcane, and as long as I could get by without it, I would. Then I began working on an app that had to process 1,000 files at a time. As I delved into that app, it became very clear that the app would have to do its heavy lifting in the background. Moreover, with the prevalence of multi-core processors, there was no way to justify writing the app without parallel processing support.

What I was writing was an app to add a visible time stamp to time-lapse photography images. Time-stamping is a very time-consuming operation, particularly when working with 1,000 images at a time. The application would obviously benefit from background and parallel processing, and it clearly needed a progress dialog that could cancel processing on request. So, I took two Aspirin and started figuring out how to add all those features to what I had thought would be a simple program.

As I was researching the issue online, I discovered the Task Parallel Library (TPL) in .NET 4. It is a truly amazing library, but I couldn't find an end-to-end tutorial on using the library, particularly in an MVVM context. The remainder of this article demonstrates the solution that I developed for the problem, in the context of the demo project attached to this article.

The Demo Project

The demo project is organized as an MVVM app. Each view element in the application (the main window and the Progress dialog) has its own View Model. Unlike some other MVVM apps, the View doesn't create its View Model, nor does the View Model create its View. Instead, the View and View Model are both created by a coordinator that is superior to both objects. For example, the main window is owned by the application, so the main window and its View Model are both created by the App object, in an override to the OnStartup() event handler:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    // Set up the main window and its view model
    var mainWindow = new MainWindow();
    var mainWindowViewModel = new MainWindowViewModel();
    mainWindow.DataContext = mainWindowViewModel;
    mainWindow.Show();
}

Read more: Codeproject
QR: Inline image 1