views:

55

answers:

4

I'm familiar with the control's dispatcher object but that doesn't solve my issue in an MVVM scenario.

I've got a UI command, that calls a method on my VM, that spawns a thread and then returns, when the thread is done (background worker might be good for this?) it will raise a callback, but the trick is, that callback modifies an observable collection, so how can I raise this callback on the UI thread?

+1  A: 

If the callback method is in a form or control with access to the Dispatcher, you can call CheckAccess(). If you're on the same thread, then just do the work. Otherwise, use the dispatcher to post a delegate to the executing function, which will then be on the correct thread.

John Fisher
+1  A: 

A background worker will work great for this.

As for publishing your change on the UI thread, all you need to do is have your callback tie into your dispatcher, and use dispatcher.Invoke to actually change the observable collection.

This is why it's almost always very handy to make your ViewModel class keep a reference to the dispatcher. This makes this pattern very easy to implement.

Reed Copsey
+3  A: 

Use the Dispatcher associated with the UI thread. Normally you would have a base ViewModel class that exposes the Dispatcher to all subclasses. Then your VM would do something like:

Dispatcher.Invoke((ThreadStart) delegate
{
    //this code executes on the UI thread
});

HTH, Kent

Kent Boogaart
A: 

A BackgroundWorker would be perfect for this, because it raises the RunWorkerCompleted event on the appropriate thread, based on the SynchronizationContext (which, in WPF, depends on the current dispatcher).

Another option is to save the current dispatcher (Dispatcher.CurrentDispatcher) before you execute the asynchronous operation, so that you can use it to invoke your callback.

I wrote a class to handle this kind of issue for observable collections, you can find it here

Thomas Levesque