2

I am not really sure about what is the best way to deal with operations executed in background threads in an application I am writing.

I am writing it in C# and I am following the MVVM design pattern. Some user actions are expensive and I'd like to run them in a background thread, which is a quite straightforward approach.

The worker thread then modifies my model, which notifies the ViewModel that something changed and finally the change gets propagated to the View.

My problem is that the chain of events triggered would cause the modification of the View from the background thread, when it is only allowed in the UI thread.

I know I can use the UI thread dispatcher but I am not really sure where (could the view-model be the right place?) so I'd like to know if you follow any design pattern to address this situation.

2 Answers 2

1

For scenarios like this, you should be using either BackgroundWorker or Task.

Example code for BackgroundWorker usage:

var bw = new BackgroundWorker();
bw.DoWork += LongRunningBackgroundWork;
bw.RunWorkerCompleted += LongRunningBackgroundWorkCompleted;
bw.RunWorkerAsync();

void LongRunningBackgroundWork(object sender, DoWorkEventArgs e)
{
    // Perform long running task/work
    // Stuff e.Result with results
}

// this runs on the thread that kicked off BackgroundWorker
void LongRunningBackgroundWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Access results from e.Result
    // Any exceptions from e.Error
    // Update ViewModel and inturn UI with the results
}

Refer to this MSDN How-to for step-by-step example on BackgroundWorker usage.

Example Code for Task Usage:

var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Run(() =>
{
    // Long running Background work
    // return Results
}).ContinueWith(task =>
{
    // access results from "task.Result"
    // any errors from task.Exception and task.Exception.InnerExceptions
    // Update ViewModel inturn UI with the results
}, uiScheduler); // Pass the UI Scheduler, so that this task runs on UI thread!

And refer to this MSDN How-to for step-by-step example on scheduling work on UI thread.

2

In WinForms, I used InvokeIfRequired to solve this. I haven't worked much with WPF, but this guy writes about WPF equivalent of InvokeIfRequired: http://blog.somecreativity.com/2008/01/10/wpf-equivalent-of-invokerequired/

Not much of an answer, but better than nothing, I hope :)

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.