My questions are many. Since I saw. NET 4.5, I was very impressed. Unfortunately all my projects are .NET 4.0 and I am not thinking about migrating. So I would like to simplify
You should just use the Task Parallel Library (TPL). The key is specifying the TaskScheduler
for the current SynchronizationContext
for any continuations in which you update the UI. For example:
Task.Factory.StartNew(() =>
{
return ProcessMethod(yourArgument);
})
.ContinueWith(antecedent =>
{
UpdateView(antecedent.Result);
},
TaskScheduler.FromCurrentSynchronizationContext());
Aside from some exception handling when accessing the antecedent's Result
property, that's all there is too it. By using FromCurrentSynchronizationContext()
the ambient SynchronizationContext that comes from WPF (i.e. the DispatcherSynchronizationContext) will be used to execute the continuation. This is the same as calling Dispatcher.[Begin]Invoke
, but you are completely abstracted from it.
If you wanted to get even "cleaner", if you control ProcessMethod I would actually rewrite that to return a Task
and let it own how that gets spun up (can still use StartNew
internally). That way you abstract the caller from the async execution decisions that ProcessMethod might want to make on its own and instead they only have to worry about chaining on a continuation to wait for the result.
UPDATE 5/22/2013
It should be noted that with the advent of .NET 4.5 and the async language support in C# this prescribed technique is outdated and you can simply rely on those features to execute a specific task using await Task.Run
and then execution after that will take place on the Dispatcher thread again automagically. So something like this:
MyResultType processingResult = await Task.Run(() =>
{
return ProcessMethod(yourArgument);
});
UpdateView(processingResult);