Reputation:
I would like to know what is the best asynchronous way to execute a task on the main thread of a .NET application (in a ViewModel to be precise). Is Dispatcher.BeginInvoke still valid nowadays or does it exist a better way to do that ?
Upvotes: 4
Views: 4055
Reputation: 457422
BeginInvoke
is very low-level; there's always a better approach available.
In most cases, you can use async
/await
to kick off an asynchronous operation from the UI thread, and automagically return to the UI thread to display results. By default, the UI context is captured by await
and used to resume the async
method after the awaited operation completes. (I describe this in more detail on my blog).
If you need to display progress reports from your UI, the best option is the IProgress<T>
/Progress<T>
types, which again do all the thread marshalling for you.
Finally, if you do need to update the UI with an unending sequence of data, the best option is to use Reactive Extensions and observe on a captured SynchronizationContext
.
These options are from most common to least common. I'd guesstimate that 90% of use cases are covered with just async
/await
, 99% covered with async
/await
+ IProgress<T>
, and 100% covered with Rx. I have never run into a case where BeginInvoke
is necessary. Or even beneficial.
Upvotes: 6
Reputation: 61379
If you need to marshal actions onto the UI thread, yes, BeginInvoke
is still the correct approach.
If you are already on the UI thread, but don't want your operation to block you can use await
/async
. Do note that this can still block your UI thread if the work being done isn't actually asynchronous and you are just wrapping it in a Task.Run
.
Upvotes: 2