当前位置:   article > 正文

WPF异步更新UI的两种方法

wpf异步更新ui

首先强调一点:异步更新UI实际上就是新开一个线程,执行耗时的任务,但是UI上的东西又不能被其他线程访问,所以非UI线程分析UI的那几条代码用一种特殊的方法来执行,从而实现既可以将耗时的操作放在其他线程,有可以更新UI。
1、方法一
案例:UI上有三个TextBlock,一个Button,当点击button的时候新三个task产生随机数(模拟耗时操作),然后将产生的随机数给UI显示

        private void Button_Click(object sender, RoutedEventArgs e)
        {
        //也可以Task task = new Task(SchedulerWork);task .Start()
            Task.Factory.StartNew(SchedulerWork);
        }               

        private void SchedulerWork()
        {
        //fistr,second,three是三个TextBlock控件的名字
            Task task = new Task((tb) => Begin(this.first), this.first);
            Task task2 = new Task((tb) => Begin(this.second), this.first);
            Task task3 = new Task((tb) => Begin(this.Three), this.first);
            task.Start();
            task2.Start();
            task3.Start();
            Task.WaitAll(task, task2, task3);
        }

        private void Begin(TextBlock tb)
        {
            int i = 100000000;
            while (i > 0)
            {
                i--;
            }
            Random random = new Random();
            String Num = random.Next(0, 100).ToString();
            this.Dispatcher.BeginInvoke(new Action(() => tb.Text = Num));
          }           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

主要注意的几点:
1、Begin方法不是在UI线程上执行的,所以他里面不能访问UI上的元素,也就是不能执行tb.Text = Num,否则他就是会报异常:(A first chance exception of type ‘System.InvalidOperationException’ occurred in WindowsBase.dll
Additional information: The calling thread cannot access this object because a different thread owns it.)
2、因此我们更新UI的部分采用:
this.Dispatcher.BeginInvoke(new Action(() => tb.Text = Num));
方法来进行更新,这样实际上就交给UI线程来做了,也就不会报错了。

2 方法二
直接上代码

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Task.Factory.StartNew(SchedulerWork);
        }

        private readonly TaskScheduler _syncContextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

        private void SchedulerWork()
        {
            Task task = new Task((tb) => Begin(this.first), this.first);
            Task task2 = new Task((tb) => Begin(this.second), this.first);
            Task task3 = new Task((tb) => Begin(this.Three), this.first);
            task.Start();
            task2.Start();
            task3.Start();
            Task.WaitAll(task, task2, task3);
        }

        private void Begin(TextBlock tb)
        {
            int i = 100000000;
            while (i > 0)
            {
                i--;
            }
            Random random = new Random();
            String Num = random.Next(0, 100).ToString();
            Task.Factory.StartNew(() => tb.Text = Num, new CancellationTokenSource().Token, TaskCreationOptions.None, _syncContextTaskScheduler).Wait();
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

下一篇讲讲CancellationTokenSource的作用

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/884966
推荐阅读
相关标签
  

闽ICP备14008679号