我的印象是,dispatcher
將按照優先級的業務 排隊,並執行基於優先級 或在其中操作被添加到隊列的順序操作(如果同樣的優先權) ,直到我被告知這不是WPF UI dispatcher
的情況。瞭解WPF Dispatcher.BeginInvoke
有人告訴我,如果UI線程上的操作需要更長的時間,比如數據庫讀取數據庫爲 ,UI調度程序簡單程序會嘗試執行隊列中的下一組操作。 我無法接觸它,因此決定編寫一個示例WPF應用程序,其中包含一個按鈕和三個矩形,單擊按鈕時,矩形會填充不同的顏色。
<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>
,並在代碼隱藏
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");
}
}
註釋代碼按預期工作的方法是基於DispatcherPriority
調用,我也能看到屏幕刷新每個操作完成後。 Order
是One, Two, Three
。顏色依次繪製。
現在的工作代碼,其中DispatcherPriority
沒有提到 (我相信它會默認爲Normal
)的順序仍是One, Two, Three
但如果我表現出MessageBox
方法裏面,Thrid
彈出窗口顯示第一則Two
然後One
但是當我調試時,我可以看到按預期順序調用的方法是
(IntelliTrace甚至顯示消息框顯示,但當時我沒有在屏幕上看到它,只有在最後一個操作完成後才能看到它。 )它只是MessageBox
es以相反的順序顯示。
是因爲MessageBox.Show
是一個阻塞調用和消息已被關閉後的操作將被清除。
即使這樣,MessageBox
的訂單也應該是One
,Two and
三`?
這簡直是在您關閉該消息框的順序的影響。由於最後一個位於頂部,這是您關閉的第一個。與DispatcherPriority沒有任何關係。 – 2014-09-22 17:35:21
是的,我認爲是這樣,但在關閉最上面的那個之前我無法看到其他的MessageBox。 – 2014-09-23 04:42:47
@ Vignesh.N我的答案解釋了您的查詢嗎? – 2016-09-27 05:34:49