我有一个ObservableCollection<Customer>()
,出于测试目的,我有一个简单的for循环,可以添加2,000,000个带随机数的记录进行搜索。当我点击加载客户时,这显示了一个漂亮的微调器并且工作正常。
private async void button_Click(object sender, RoutedEventArgs e)
{
bool result = DatabaseMaster.CheckConnection(con);
spinner.Visibility = Visibility.Visible;
spinner.Spin = true;
customers = await Task.Run(()=>DatabaseMaster.GetCustomers());
customerListBox.ItemsSource = customers;
spinner.Visibility = Visibility.Collapsed;
spinner.Spin = false;
}
但是,我有一个用于搜索的文本框,并希望搜索客户并更新视图。我试过了
await Task.Run(()=>customerListBox.ItemsSource = customers.Where(X => X.name.ToLower().Contains(searchTextBox.Text.ToLower())));
然而,这通过调用线程的错误无法访问此对象,因为另一个线程拥有它。
我尝试这个但是UI仍然会在更新项目源时跳转。任何想法或我应该了解更多inotifypropertychanged?
private async void search_TextChanged(object sender, TextChangedEventArgs e)
{
spinner.Visibility = Visibility.Visible;
spinner.Spin = true;
customerListBox.Background = Brushes.Gray;
customerListBox.IsEnabled = false;
await this.Dispatcher.BeginInvoke(new Action(() =>
{
customerListBox.ItemsSource = customers.Where(X => X.name.ToLower().Contains(searchTextBox.Text.ToLower()));
}), null);
customerListBox.Background = Brushes.White;
customerListBox.IsEnabled = true;
spinner.Visibility = Visibility.Collapsed;
spinner.Spin = false;
}
答案 0 :(得分:2)
看起来customers
只是一个本地集合。通常在另一个线程中查询它没有多大意义。但是,如果您仍然需要它,请确保仅在UI线程中使用UI对象(示例中为customerListBox
)。
像
var text = searchTextBox.Text.ToLower();
var r = await Task.Run(() => customers.Where(X.name.ToLower().Contains(text).ToList());
customerListBox.ItemsSource = r;
答案 1 :(得分:0)
如果您将代码更改为以下它应该可以工作(因为itemsource将在ui线程中而不是在任务内部分配
customerListBox.ItemsSource = await Task.Run(()=> customers.Where(X => X.name.ToLower().Contains(searchTextBox.Text.ToLower())));