在wpf中,更新UI上面的数据,那是必经之路,搞不好,就是死锁,或者没反应,很多时候,都是嵌套的非常深导致的。但是更新UI的方式,有很多的种,不同的方式,表示的意思不一样,但是眼睛看到的,似乎是一回事。
首先我们创建一个简单的wpf程序
业务就是,一直点击确定,然后更新数据即可,比较简单,通过简单的案例来了解一个wpf中更新UI的4种方法。
第一种:
点击确定后,界面先变化Hello WPF11,再变化Hello WPF12,并且界面可以任意拖动不卡。
这个方法是全局性质的。
using System.Windows;
namespace WpfApp6Demo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void btnLogin_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF11");
});
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF12");
});
}
private void UpdateTextBlock(string text)
{
System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
{
txtUsername.Text = text;
}));
}
}
}
第二种:
点击确定后,和前面的效果是一样的。
这个方法是当前界面性质的。
using System.Windows;
namespace WpfApp6Demo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void btnLogin_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF11");
});
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF12");
});
}
private void UpdateTextBlock(string text)
{
//System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
//{
// txtUsername.Text = text;
//}));
this.Dispatcher.Invoke(new Action(() =>
{
txtUsername.Text = text;
}));
}
}
}
第三种:
点击确定后,和前面的效果是一样的。
这个方法是当前控件性质的。
using System.Windows;
namespace WpfApp6Demo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void btnLogin_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF11");
});
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF12");
});
}
private void UpdateTextBlock(string text)
{
//System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
//{
// txtUsername.Text = text;
//}));
//this.Dispatcher.Invoke(new Action(() =>
// {
// txtUsername.Text = text;
// }));
txtUsername.Dispatcher.Invoke(new Action(() =>
{
txtUsername.Text = text;
}));
}
}
}
第四种:
点击确定后,和前面的效果是一样的。
这个方法是当前控件性质的,但是还对当前控件进行是否有访问权限进行了判断。
using System.Windows;
namespace WpfApp6Demo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void btnLogin_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF11");
});
await Task.Run(() =>
{
// 耗时操作
Thread.Sleep(2000);
UpdateTextBlock("Hello WPF12");
});
}
private void UpdateTextBlock(string text)
{
//System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
//{
// txtUsername.Text = text;
//}));
//this.Dispatcher.Invoke(new Action(() =>
// {
// txtUsername.Text = text;
// }));
//txtUsername.Dispatcher.Invoke(new Action(() =>
//{
// txtUsername.Text = text;
//}));
if (!txtUsername.Dispatcher.CheckAccess())
{
txtUsername.Dispatcher.Invoke(new Action<string>(UpdateTextBlock), text);
}
else
{
txtUsername.Text = text;
}
}
}
}
以上都是以同步Invoke的方式进行调用的,异步的话使用BeginInvoke。
总结:通过案例,可以了解到,上面4种方式,对于此案例来说都可以达到最终的效果,但是那一种效果最好,并没有体现出来。博主认为:第三种最好,原因是从这个需求上考虑的,因为需求需要更新的就是txtUsername上面的数据,那么直接作用于它,对于资源的耗损,将是最少得。可能有人认为第四种方式最好,进行了线程判断,似乎更加的安全,那么您认为呢???
本文来源:
wpf线程中更新UI的4种方式-CSDN博客