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>
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
- {
- /// <summary>
- /// Interaction logic for MainWindow.xaml
- /// </summary>
- 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);
- }
- }
- }
- }
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.
Related Link: Threads in WPF
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:
manish singhPosted Jan 25, 2020, 3:21 PM
You can use CheckAccess before calling the disptacher.
Johnny AncichPosted Nov 20, 2019, 1:17 PM
Such a shame this does not worth with winforms.
Helvetier1 Helvetier1Posted Sep 16, 2018, 3:27 PM
Thanks man! This was a really good one.
vivek sharmaPosted Mar 28, 2018, 12:26 PM
Thanks a lot... brother, u really saved me.. this works like a charm..
ashok rathodPosted Mar 22, 2016, 1:16 AM
Good one
Former memberPosted Feb 29, 2016, 1:03 AM
Thanks
Sibeesh VenuPosted Feb 25, 2016, 12:43 AM
Nice Share
Raja TPosted Feb 24, 2016, 11:05 PM
Good.Thanks for sharing
Mohammed IbrahimPosted Feb 24, 2016, 3:57 PM
nice
Former memberPosted Feb 24, 2016, 10:38 AM
Thanks
Santhakumar MunuswamyPosted Feb 24, 2016, 10:28 AM
Thanks for nice article