Verständnis war ich unter dem Eindruck, dass die dispatcher
der Priorität der Operationen es die Warteschlange folgen und die Operationen basierend auf der Priorität oder die Reihenfolge, in der die Operation ausgeführt zu der Warteschlange hinzugefügt wurde (wenn gleiche Priorität) bis mir gesagt wurde, dass dies im Fall der WPF UI dispatcher
nicht der Fall ist.die WPF Dispatcher.BeginInvoke
Ich wurde gesagt, dass, wenn eine Operation auf dem UI-Thread längere Dauer dauert sagen eine Datenbank lesen der UI Dispatcher einfach versucht, nächste Reihe von Operationen in der Warteschlange auszuführen. Ich konnte mich nicht damit abfinden, also entschied ich mich, eine Beispiel-WPF-Anwendung zu schreiben, die eine Schaltfläche und drei Rechtecke enthält. Auf einen Klick werden die Rechtecke mit verschiedenen Farben gefüllt.
<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>
und in der 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");
}
}
Die kommentierten Code funktioniert wie erwartet die Methoden aufgerufen werden basierend auf dem DispatcherPriority
und ich erhalte auch die Aktualisierung des Bildschirms zu sehen, nachdem jeder Vorgang abgeschlossen wurde. Order
ist One, Two, Three
. Farben werden nacheinander gezeichnet.
Nun wird der Arbeits Code, in dem die DispatcherPriority
nicht erwähnt wird (ich nehme an, es zu Normal
Standard würde) die Reihenfolge noch One, Two, Three
ist, aber wenn ich ein MessageBox
in den Methoden zeigen, der Thrid
Popup zeigt zunächst dann Two
dann One
aber wenn ich debugge, könnte ich sehen, dass die Methoden
in der erwarteten Reihenfolge aufgerufen werden (IntelliTrace zeigt sogar, dass ein Meldungsfeld angezeigt wird, aber ich sehe es nicht auf dem Bildschirm zu dieser Zeit und sehe es erst nach dem letzten Vorgang abgeschlossen ist.) Es ist nur, dass die MessageBox
es in umgekehrter Reihenfolge angezeigt werden.
Liegt daran, dass MessageBox.Show
ein blockierender Anruf ist und die Operation gelöscht wird, nachdem die Nachricht geschlossen wurde.
Auch dann sollte die Reihenfolge der MessageBox
auch One
, Two and
Drei sein?
Dies wird nur von der Reihenfolge beeinflusst, in der Sie die Meldungsfelder schließen. Da der letzte oben ist, ist das der erste, den du schließe. Hat nichts mit DispatcherPriority zu tun. –
Ja..Ich dachte, aber ich bin nicht in der Lage, die anderen 'MessageBox's zu sehen, bevor ich den obersten schließe. –
@ Vignesh.N erklärt meine Antwort Ihre Frage? –