Mike Schwartz
Mike Schwartz

Reputation: 2212

Simple wpf mvvm asynchronous example

I have very simple restful service that handles all data requests for my wpf application. I know that the best practice indicates getting those long running requests off of the UI thread.

I'm using .NET 4.5 so I can utilize some of the newer tools, async/await, TPL. I've created some sample projects and I understand the concept. Problem that I just can't seem to get a grasp on is handling the async stuff in the viewmodel. In my sample projects, the async work always happens in the codebehind - easy enough. Once its abstracted to the viewmodel - I lose it.

I have a very simple generic class that handles all of my rest web reqeusts. Ideally I want the async work to happen there.

Upvotes: 1

Views: 2971

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456977

Here's what I recommend for async MVVM projects:

  • Treat your VM like it has UI affinity.
  • Async methods are commonly used for initialization and commands.
  • Properties only represent the current state. If you find yourself trying to implement an "asynchronous property", re-evaluate your design.

With that said, there are some techniques that you may find helpful (all of these are links to my blog or my AsyncEx library).

I have a blog post on async and constructors; the "asynchronous initialization" technique (which is compatible with IoC) is the one I recommend for VMs.

I also have a blog post on async and properties; there are a couple of approaches including async lazy initialization (for shared resources) and updating data-bound properties. Both of these blog posts are part of an async OOP series, but those two in particular have useful information for VMs.

Both async initialization and async property loading can use a helper type I wrote called NotifyTaskCompletion, which essentially just observes a task and provides some data-bindable properties for that task.

For async commands (ICommand), you could start out with the SimpleAsyncCommand, which is like an async DelegateCommand. A more advanced type is the AsyncCommand, which supports cancellation, progress reporting, and has a default implementation of CanExecuteChanged returning false as long as the command is already executing.

Note that SimpleAsyncCommand and AsyncCommand are not yet part of AsyncEx, so you'll have to copy/paste the source into your own project to make use of them.

Upvotes: 4

Related Questions