2017-06-01 89 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