2017-06-01 78 views
1

我有一个ObservableCollection<Customer>()和出于测试的目的,我有简单的循环,添加2,000,000记录与随机数字搜索。当我点击加载客户,这显示一个不错的微调,并正常工作。等待列表框完成呈现WPF

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; 
    } 

但是,我有一个文本框用于搜索,并希望搜索客户并更新视图。我试图

然而,这通过调用线程的错误,因为不同的线程拥有它不能访问该对象。

我尝试这个,但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

执行'Where'在后台被分配任务,只更新ui线程中的'ItemsSource',当有很多条目时它仍然会闪烁 – NtFreX

+1

请注意,'.Where(...)'实际上并没有那么多,如果你想在任务,你需要调用'.Where(...).ToList()'。 – grek40

+0

@ grek40它当我输入我的文本框时仍然冻结,因为当它冻结时它甚至不显示我的微调器? – Bish25

回答

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; 
+0

当我添加这个UI时,界面仍然冻结,它会冻结大约4秒钟然后响应。我相信它是这条线'customerListBox.ItemsSource = r;'导致问题 – Bish25

+0

@ bish25你可能尝试了没有'ToList()'的第一个版本。尝试当前的一个 –

+0

当我尝试,我得到错误'调用线程不能访问此对象,因为不同的线程拥有它。' ' – Bish25

0

如果你改变你的代码如下它应该工作(因为会的ItemSource在UI线程,而不是任务的内部

customerListBox.ItemsSource = await Task.Run(()=> customers.Where(X => X.name.ToLower().Contains(searchTextBox.Text.ToLower()))); 
+0

它仍然冻结了大约3秒钟,它甚至不会在ui线程上显示我的微调,这让我相信它的UI本身减慢了它的速度 – Bish25