我的印象是,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