WPF中Dispatcher调度程序小探

     Dispatcher,即调度程序,在每个线程中都唯一存在,负责线程中数据的各项操作。例如线程A创建了实例I,则线程B就不能直接去更新I,而必须通过线程A来委托处理。下面举个简单的例子。

     有如下简单的XAML代码,一个Label用于显示,两个Button用于更新Label数据:

    

代码
<Grid>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="129,147,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="129,69,0,0" Name="label1" VerticalAlignment="Top" Width="207" />
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="244,147,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
</Grid>

在button1中:

 

private void button1_Click(object sender, RoutedEventArgs e)
{
label1.Content
= "Updated by button1.";
}

 

很显然这样可以更新label1中的数据,因为label1,button1,button2都是窗口创建时由主线程创建的,所以它们的 Dispatcher是一样的。但是假如我们在点击之后创建一个新的线程去更新label1会发生什么呢?不妨试试!

 

代码
private void button2_Click(object sender, RoutedEventArgs e)
{
Thread updateThread
= new Thread(UpdateLabel);
updateThread.Start();
}

private void UpdateLabel()
{
label1.Content
= "Updated by button2.";
}

 

当我们点击button2,铛铛铛铛~~

O了,没有权限!那就对了!下面给出解决的方法,其实原理很简单,你不让我访问,那我告诉你该这么做,你自己去做呗~~

 

代码
private void button2_Click(object sender, RoutedEventArgs e)
{
Thread updateThread
= new Thread(UpdateLabel);
updateThread.Start();
}

private delegate void UpdateLabelDelegate();

private void UpdateLabel()
{
label1.Dispatcher.Invoke(
new UpdateLabelDelegate(UpdateLabelAction));
}

private void UpdateLabelAction()
{
label1.Content
= "Updated by button2.";
}

 

首先定义一个托管UpdateLabelDelegate,你也尽可以创建一个带参数的托管。 label1.Dispatcher就是调用label1的调度程序,它当然有操作label1的权限,然后通过Invoke函数调用托管函数,就是这么简单!(Invoke方法是同步操作,还有一个异步操作BeginInvoke)

 

第一次在园子里发文,希望大家多指教!

posted @ 2010-03-25 13:43  DeeRoad  阅读(1707)  评论(0编辑  收藏  举报