WPF之Dispatcher

WPF启动后的两个线程:一个线程负责呈现,它隐藏在后台运行。另一个线程负责UI界面管理,主要接收收入、处理事件、绘制屏幕以及运行应用程序代码,即UI线程。

WPF中每个界面及界面中的控件都继承自DispatcherObject类,DispatcherObject包含一个公共属性Dispatcher。当前执行的主窗体及各个控件,在初始化时就都自动赋值了Dispatcher属性,并且都指向同一个UI线程所拥有的Dispatcher对象。

1.Dispatcher两个注册工作项的方法:

Invoke 和 BeginInvoke。这两个方法都是通过调度一个委托来执行。其中Invoke 是同步调用,也就是说,直到 UI 线程实际执行完该委托它才返回。而BeginInvoke是异步的,将立即返回。

2.Dispatcher的使用:

1).解决“从一个非 UI 线程中更新一个由UI线程创建的对象”。

在一个子线程中直接访问或更新UI线程创建的对象,会报异常。因为DispatcherObject对象只能被创建它的线程所访问,其他线程修改 DispatcherObject需要取得对应的Dispatcher,调用Invoke或者BeginInvoke来投入任务。所以此时我们可以利用Dispatcher的Invoke或BeginInvoke方法来完成对UI线程上控件的更新。

例如:另一个线程中更新Lable控件的内容

//新建线程
Thread thread = new Thread(UpdateLableText);
thread.Start();
private void UpdateLableText()
{
    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
        (ThreadStart) delegate()
        {
            lable1.Text = "Hello";
        }
        );
}

2).避免在Dispatcher中处理耗时操作

Dispatcher会给UI的工作队列进行优先级排队。当某一个耗时操作发生在UI线程上时,Dispatcher工作队列中其他项就需要等待,可能会出现用户界面卡死的现象。所以建议开一个新线程去处理那些耗时的操作,处理完后,可以通过向UI线程的Dispatcher队列注册工作项来通知UI线程更新结果即可。也可以说,Dispatcher利用主线程进行任务优先级的排列来模拟多线程,因此其中实质是单线程。

比如一个求和显示的耗时操作,建议新开一个线程来完成耗时的求和运算,得出求和结果后,在调用主线程Dispatcher来显示结果。

Thread thread = new Thread(UpdateLableText);
thread.Start();
private void UpdateLableText()
{
    string result = GetSum(); //将耗时的操作放在thread线程中处理,而不是Dispatcher中
    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
        (ThreadStart) delegate()
        {
           //string result = GetSum(); //一个耗时的求和操作
            lable1.Text = result;
        }
        );
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值