The Dispatcher
class is a very common way of accessing the UI thread while we are on another thread.
With WPF 4.5 we have some new methods for synchronous and asynchronous operations, which make this Dispatcher
class more async and await friendly. Another improvement is that Dispatcher.Invoke
and Dispatcher.InvokeAsync
are now able to return a value.
Finally, we also have a new parameter of CancellationToken
type, which provides the obvious capability of being able to cancel dispatched tasks.
In the following steps we will see how to use the Dispatcher
class to dispatch a task that accesses the UI thread.
WPFDispatcher
.MainWindow.xaml
view and add a Button Click event, name it btnDispatcher
and enter 1
as the content.MainWindow.xaml.cs
code and change the MainWindow
class code as follows:public MainWindow() { InitializeComponent(); this.btnDispatcher.Click += btnDispatcher_Click; } void btnDispatcher_Click(object sender, RoutedEventArgs e) { TestNewDispatcherAsyncMethod(); } public async void TestNewDispatcherAsyncMethod() { // Usage of the InvokeAsync method var TaskDoSomething = await Dispatcher.InvokeAsync<Task<string>>(DoSomething); // We wait for the task to finish TaskDoSomething.Wait(); // Getting the result from the finished task string resultFromTask = TaskDoSomething.Result; // Usage of the Invoke method which returns a value of a defined type var returnedOject = Dispatcher.Invoke<string>( DoSomethingElse); } private string DoSomethingElse() { return "hi"; } private async Task<string> DoSomething() { //As we are being dispatched we could access the UI thread and update-change something there... String num = this.btnDispatcher.Content.ToString(); int iNum; int.TryParse(num, out iNum); iNum = iNum + 1; this.btnDispatcher.Content = iNum.ToString(); return "I should do something..."; }
We have used one of the new Dispatcher
methods, which can be called asynchronously.
// Usage of the InvokeAsync method var TaskDoSomething = await Dispatcher.InvokeAsync<Task<string>>(DoSomething);
The example illustrates how to receive the result of Task
where we are changing a UI element and returning a value.
We can observe that we are executing a dispatcher operation asynchronously, which is in sync with the UI thread.
We are also invoking it in the usual non-asynchronous way with:
// Usage of the Invoke method which returns a value of a defined type var returnedOject = Dispatcher.Invoke<string>( DoSomethingElse);
As you can see, we can now return a result value of a specific type with a Dispatcher.Invoke
method.
To complete the example, the DoSomething
asynchronous method makes a very simple change on the UI thread.
If we take a look at the new methods that the Dispatcher
class provides, we find the CancellationToken
method, which enables us to cancel an action (or prevent it from being executed). This method belongs to the .NET 4.0 Cancellation Framework, which is useful for a proper implementation of the unit of work pattern.
We just saw how to use two of the most useful new methods, but there are a lot more to be explored.