zoukankan      html  css  js  c++  java
  • Dispatcher的Invoke和BeginInvoke

    WPF的应用程序运行时,就有一个主线程(UI线程)和其他的一些子线程。

    子线程是不能修改UI线程,必须通过UI线程的Dispatcher来完成。

    简单点来说:子线程是不能修改程序UI的,除非用UI线程的Dispatcher来注册。

    例如:

    private void Invoke_Button(object sender, RoutedEventArgs e)
      {
                Task.Run(() =>
                {
                    Thread.Sleep(1000);
                    this.TextBlock.Text = "10";
                });
            }

    另起一个线程去修改UI上TextBlock控件的值。就会报异常:System.InvalidOperationException: '调用线程无法访问此对象,因为另一个线程拥有该对象。'

    Dispatcher两种注册方式:

    Invoke:同步调用,即会在子线程执行完成后返回。

    private void Invoke_Button(object sender, RoutedEventArgs e)
            {
                Task.Run(() =>
                {
                    Dispatcher.Invoke(() =>
                    {
                        Thread.Sleep(5000);
                        this.TextBlock.Text = "10";
                    });
                });
            }

    BeginInvoke:异步调用,即立即返回。

    private void BeginInvoke_Button(object sender, RoutedEventArgs e)
            {
                Task.Run(() =>
                {
                    Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                    {
                        this.TextBlock.Text = "3";
                        Thread.Sleep(10000);
                    }));
                });
            }

    总结:当在子线程中调用Dispather注册时,Dispatcher中的Action依然还是占用着UI线程,所以Dispatcher的工作项依然是越少越少,耗时操作越少越好。

    BeginInvoke效率要更高一点。反应更灵敏。

  • 相关阅读:
    docker应用部署
    Netty实现WebSocket通信
    spring-mvc框架简单搭建
    spring-tx 事物
    spring注解及简单实用
    Spring Aop实现简单代码实现
    Jedis操作
    Proxy说明
    下载返回流
    向上捅破天,向下扎到根
  • 原文地址:https://www.cnblogs.com/ljdong7/p/13692316.html
Copyright © 2011-2022 走看看