不灬赖

自律>>自由>>自信

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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效率要更高一点。反应更灵敏。

 

posted on 2020-09-18 17:09  不灬赖  阅读(993)  评论(0编辑  收藏  举报