当前位置:   article > 正文

wpf线程中更新UI的4种方式_wpf 线程更新ui

wpf 线程更新ui

        在wpf中,更新UI上面的数据,那是必经之路,搞不好,就是死锁,或者没反应,很多时候,都是嵌套的非常深导致的。但是更新UI的方式,有很多的种,不同的方式,表示的意思不一样,但是眼睛看到的,似乎是一回事。

首先我们创建一个简单的wpf程序

业务就是,一直点击确定,然后更新数据即可,比较简单,通过简单的案例来了解一个wpf中更新UI的4种方法。 

第一种:

点击确定后,界面先变化Hello WPF11,再变化Hello WPF12,并且界面可以任意拖动不卡。

这个方法是全局性质的。

  1. using System.Windows;
  2. namespace WpfApp6Demo
  3. {
  4. /// <summary>
  5. /// Interaction logic for MainWindow.xaml
  6. /// </summary>
  7. public partial class MainWindow : Window
  8. {
  9. public MainWindow()
  10. {
  11. InitializeComponent();
  12. }
  13. private async void btnLogin_Click(object sender, RoutedEventArgs e)
  14. {
  15. await Task.Run(() =>
  16. {
  17. // 耗时操作
  18. Thread.Sleep(2000);
  19. UpdateTextBlock("Hello WPF11");
  20. });
  21. await Task.Run(() =>
  22. {
  23. // 耗时操作
  24. Thread.Sleep(2000);
  25. UpdateTextBlock("Hello WPF12");
  26. });
  27. }
  28. private void UpdateTextBlock(string text)
  29. {
  30. System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
  31. {
  32. txtUsername.Text = text;
  33. }));
  34. }
  35. }
  36. }

第二种:

点击确定后,和前面的效果是一样的。

这个方法是当前界面性质的。

  1. using System.Windows;
  2. namespace WpfApp6Demo
  3. {
  4. /// <summary>
  5. /// Interaction logic for MainWindow.xaml
  6. /// </summary>
  7. public partial class MainWindow : Window
  8. {
  9. public MainWindow()
  10. {
  11. InitializeComponent();
  12. }
  13. private async void btnLogin_Click(object sender, RoutedEventArgs e)
  14. {
  15. await Task.Run(() =>
  16. {
  17. // 耗时操作
  18. Thread.Sleep(2000);
  19. UpdateTextBlock("Hello WPF11");
  20. });
  21. await Task.Run(() =>
  22. {
  23. // 耗时操作
  24. Thread.Sleep(2000);
  25. UpdateTextBlock("Hello WPF12");
  26. });
  27. }
  28. private void UpdateTextBlock(string text)
  29. {
  30. //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
  31. //{
  32. // txtUsername.Text = text;
  33. //}));
  34. this.Dispatcher.Invoke(new Action(() =>
  35. {
  36. txtUsername.Text = text;
  37. }));
  38. }
  39. }
  40. }

第三种:

点击确定后,和前面的效果是一样的。

这个方法是当前控件性质的。

  1. using System.Windows;
  2. namespace WpfApp6Demo
  3. {
  4. /// <summary>
  5. /// Interaction logic for MainWindow.xaml
  6. /// </summary>
  7. public partial class MainWindow : Window
  8. {
  9. public MainWindow()
  10. {
  11. InitializeComponent();
  12. }
  13. private async void btnLogin_Click(object sender, RoutedEventArgs e)
  14. {
  15. await Task.Run(() =>
  16. {
  17. // 耗时操作
  18. Thread.Sleep(2000);
  19. UpdateTextBlock("Hello WPF11");
  20. });
  21. await Task.Run(() =>
  22. {
  23. // 耗时操作
  24. Thread.Sleep(2000);
  25. UpdateTextBlock("Hello WPF12");
  26. });
  27. }
  28. private void UpdateTextBlock(string text)
  29. {
  30. //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
  31. //{
  32. // txtUsername.Text = text;
  33. //}));
  34. //this.Dispatcher.Invoke(new Action(() =>
  35. // {
  36. // txtUsername.Text = text;
  37. // }));
  38. txtUsername.Dispatcher.Invoke(new Action(() =>
  39. {
  40. txtUsername.Text = text;
  41. }));
  42. }
  43. }
  44. }

第四种: 

点击确定后,和前面的效果是一样的。

这个方法是当前控件性质的,但是还对当前控件进行是否有访问权限进行了判断。

  1. using System.Windows;
  2. namespace WpfApp6Demo
  3. {
  4. /// <summary>
  5. /// Interaction logic for MainWindow.xaml
  6. /// </summary>
  7. public partial class MainWindow : Window
  8. {
  9. public MainWindow()
  10. {
  11. InitializeComponent();
  12. }
  13. private async void btnLogin_Click(object sender, RoutedEventArgs e)
  14. {
  15. await Task.Run(() =>
  16. {
  17. // 耗时操作
  18. Thread.Sleep(2000);
  19. UpdateTextBlock("Hello WPF11");
  20. });
  21. await Task.Run(() =>
  22. {
  23. // 耗时操作
  24. Thread.Sleep(2000);
  25. UpdateTextBlock("Hello WPF12");
  26. });
  27. }
  28. private void UpdateTextBlock(string text)
  29. {
  30. //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
  31. //{
  32. // txtUsername.Text = text;
  33. //}));
  34. //this.Dispatcher.Invoke(new Action(() =>
  35. // {
  36. // txtUsername.Text = text;
  37. // }));
  38. //txtUsername.Dispatcher.Invoke(new Action(() =>
  39. //{
  40. // txtUsername.Text = text;
  41. //}));
  42. if (!txtUsername.Dispatcher.CheckAccess())
  43. {
  44. txtUsername.Dispatcher.Invoke(new Action<string>(UpdateTextBlock), text);
  45. }
  46. else
  47. {
  48. txtUsername.Text = text;
  49. }
  50. }
  51. }
  52. }

以上都是以同步Invoke的方式进行调用的,异步的话使用BeginInvoke。 

总结:通过案例,可以了解到,上面4种方式,对于此案例来说都可以达到最终的效果,但是那一种效果最好,并没有体现出来。博主认为:第三种最好,原因是从这个需求上考虑的,因为需求需要更新的就是txtUsername上面的数据,那么直接作用于它,对于资源的耗损,将是最少得。可能有人认为第四种方式最好,进行了线程判断,似乎更加的安全,那么您认为呢???

本文来源:

wpf线程中更新UI的4种方式-CSDN博客

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

闽ICP备14008679号