I was under the impression that the dispatcher will follow the priority of the operations queued it and execute the operations based on the priority or the order in which the operation was added to the queue(if same priority) until I was told that this is no the case in case of the WPF UI dispatcher.
I was told that if a operation on the UI thread takes longer duration say a database read the UI dispatcher simple tries to execute next set of operations in the queue. I could not come to terms with it so decided to write a sample WPF application which contains a button and three rectangles, on click of the button, the rectangles are filled with different colors.
<StackPanel> <Button x:Name="FillColors" Width="100" Height="100" Content="Fill Colors" Click="OnFillColorsClick"/> <TextBlock Width="100" Text="{Binding Order}"/> <Rectangle x:Name="RectangleOne" Margin="5" Width="100" Height="100" Fill="{Binding BrushOne}" /> <Rectangle x:Name="RectangleTwo" Margin="5" Width="100" Height="100" Fill="{Binding BrushTwo}"/> <Rectangle x:Name="RectangleThree" Margin="5" Width="100" Height="100" Fill="{Binding BrushThree}"/> </StackPanel> and in the code-behind
private void OnFillColorsClick(object sender, RoutedEventArgs e) { var dispatcher = Application.Current.MainWindow.Dispatcher; dispatcher.BeginInvoke(new Action(() => { //dispatcher.BeginInvoke(new Action(SetBrushOneColor), (DispatcherPriority)4); //dispatcher.BeginInvoke(new Action(SetBrushTwoColor), (DispatcherPriority)5); //dispatcher.BeginInvoke(new Action(SetBrushThreeColor), (DispatcherPriority)6); dispatcher.BeginInvoke(new Action(SetBrushOneColor)); dispatcher.BeginInvoke(new Action(SetBrushTwoColor)); dispatcher.BeginInvoke(new Action(SetBrushThreeColor)); }), (DispatcherPriority)10); } private void SetBrushOneColor() { Thread.Sleep(10 * 1000); Order = "One"; //MessageBox.Show("One"); BrushOne = Brushes.Red; } private void SetBrushTwoColor() { Thread.Sleep(12 * 1000); Order = "Two"; //MessageBox.Show("Two"); BrushTwo = Brushes.Green; } private void SetBrushThreeColor() { Thread.Sleep(15 * 1000); Order = "Three"; //MessageBox.Show("Three"); BrushThree = Brushes.Blue; } public string Order { get { return _order; } set { _order += string.Format("{0}, ", value); RaisePropertyChanged("Order"); } } The commented code works as expected the methods are invoked based on the DispatcherPriority and I also get to see the screen refresh after each operation has been completed. Order is One, Two, Three. Colors are drawn one after another.
Now the working code where the DispatcherPriority is not mentioned ( I assume it would default to Normal) the order is still One, Two, Three but if I show a MessageBox inside the methods, the
Thrid popup is show first then Two then One but when I debug I could see the methods are
invoked in the expected order (IntelliTrace even shows that a message box is shown but I don't see it on the screen at that time and see it only after the last operation is finished.) its just that the MessageBoxes are shown in the reverse order.
Is it because MessageBox.Show is a blocking call and the operation are cleared after the message has been closed.
Even then the order of the MessageBox should also be One, Two andThree` ?

MessageBoxes before I close the topmost one.