WPF框架中异步、多线程、高性能与零拷贝技术应用示例
一、异步编程在WPF中的应用
1. 异步数据加载(避免UI冻结)
// ViewModel中的异步数据加载示例
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<string> _items;
public ObservableCollection<string> Items
{
get => _items;
set { _items = value; OnPropertyChanged(); }
}
public async Task LoadDataAsync()
{
// 显示加载状态
IsLoading = true;
try
{
// 模拟耗时操作
var data = await Task.Run(() =>
{
// 这里可以是数据库查询、文件读取或网络请求
Thread.Sleep(2000); // 模拟耗时操作
return new List<string> { "Item1", "Item2", "Item3" };
});
Items = new ObservableCollection<string>(data);
}
catch (Exception ex)
{
// 错误处理
MessageBox.Show($"加载数据失败: {ex.Message}");
}
finally
{
IsLoading = false;
}
}
private bool _isLoading;
public bool IsLoading
{
get => _isLoading;
set { _isLoading = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
// XAML中的使用
<Window x:Class="WpfAsyncDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="异步加载示例" Height="350" Width="525">
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<ProgressBar IsIndeterminate="{Binding IsLoading}" Width="200" Height="10"/>
<Button Content="加载数据" Click="LoadData_Click" Margin="0,10"/>
<ListBox ItemsSource="{Binding Items}" Height="200"/>
</StackPanel>
</Grid>
</Window>
// 代码后台
public partial class MainWindow : Window
{
private readonly MainViewModel _viewModel = new MainViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _viewModel;
}
private async void LoadData_Click(object sender, RoutedEventArgs e)
{
await _viewModel.LoadDataAsync();
}
}
2. 异步文件I/O操作
// 异步读取大文件
public async Task<string> ReadLargeFileAsync(string filePath)
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
using (var reader = new StreamReader(stream))
{
return await reader.ReadToEndAsync();
}
}
// 异步写入文件
public async Task WriteLargeFileAsync(string filePath, string content)
{
using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true))
using (var writer = new StreamWriter(stream))
{
await writer.WriteAsync(content);
}
}
二、多线程技术在WPF中的应用
1. 使用BackgroundWorker(传统方式)
// 在ViewModel中使用BackgroundWorker
public class BackgroundWorkerViewModel : INotifyPropertyChanged
{
private readonly BackgroundWorker _worker