Introduction
WPF application works on the principle of
Thread affinity which means other threads can't interact with each other. This is called
Single threaded apartment model. Sometimes developers need to manage the thread or update WPF UI. But,
WPF objects run on the principle of thread affinity that derives from the Dispatcher object.
So, if developers create their own thread and try to update WPF UI then thread affinity principles stops them by using the method "VerifyAccess()" of DispatcherObject class. It will throw an exception “InvalidOperationException”.
So, I will explain one code example by using "Dispatcher" and "TPL" by which you can update WPF UI. Below is the WPF code example
.XAML File:
- <Window x:Class="WpfApplication1.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <StackPanel>
- <Label Name="myLabel"></Label>
- </StackPanel>
- </Window>
Here, I took one label -
<Label Name="myLabel"></Label>
Go to code behind or .XAML.cs file:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Threading;
-
- namespace WpfApplication1
- {
-
-
-
- public partial class MainWindow : Window
- {
- public MainWindow()
- {
- InitializeComponent();
- var mySource = Enumerable.Range(1, 1000).ToList();
- Task.Factory.StartNew(() => CalculateMyOperation(mySource));
- }
-
- private void CalculateMyOperation(List<int> values)
- {
- foreach (var i in values)
- {
- var currentProgress = i;
- Dispatcher.BeginInvoke(new Action(() =>
- {
- myLabel.Content = "Updating..." + currentProgress;
- }), DispatcherPriority.Background);
- }
- }
- }
- }
Output:
Updating... 1
Updating ...2
Updating....3
...................
Updating...100
Here, I have used method "BeginInvoke" with Dispatcher because "Dispatcher.BeginInvoke" schedules the given action for execution in the UI thread and then returns control to allow the current thread to continue executing.
But, Invoke method blocks the caller until the scheduled action is completed.
The priority of dispatcher describes the priority at which the operation can be invoked. Here, I used DispatcherPriority.Background as a dispatccher priorty. The Priority "Background" explains that I will start my operation after all other non-idle operations are complete.
I defined UI updating operations inside action delegate "new Action(() =>".
Note: Please find attached code for reference.
Conclusion
Dispatcher is an important technique or concept to run an operation that will be executed on the UI thread. It updates the UI.
Read more articles on WPF: