Подтвердить что ты не робот

WPF ICollectionView.filter с большими наборами данных

Я работаю над приложением wpf, которое содержит список с довольно большим количеством данных (от 10 000 до 100 000) строк. Пользователь может применять все виды фильтров к этому списку, что делает логику фильтра довольно продвинутой (и медленной). На данный момент соответствующая часть моего кода выглядит следующим образом:

ICollectionView view = CollectionViewSource.GetDefaultView(hugeList.ItemsSource);
view.Filter = new Predicate<object>(FilterCallback);

private bool FilterCallback(object item)
{
  //Filter logic
}

Но это работает в потоке пользовательского интерфейса и блокирует все приложение при фильтрации, что дает очень плохой пользовательский интерфейс. Поэтому мой вопрос для всех вас: кто-нибудь знает "лучший" способ фильтрации списка в wpf или я должен фильтровать базовый ObservableCollection вместо этого?

4b9b3361

Ответ 1

Обратите внимание на функцию фильтра. Убедитесь, что вы не делаете ненужного бокса/распаковки, и вы не делаете в нем обширные вычисления. Вы также должны обратить внимание на то, какой вид CollectionView вы используете, а некоторые быстрее других. Из Сообщение о сортировке:

  • A CollectionView создается, если ваш источник реализует IEnumerable. Если источник реализует только IEnumerable, вы не сможете сортировать или группировать коллекцию (вы можете ее фильтровать). Кроме того, perf не будет лучшим, если источник имеет большое количество элементов или если вы выполняете динамические операции, такие как вставки и удаления. Если это ваш сценарий, вы должны подумать о том, чтобы ваш источник реализовал более сильный интерфейс. ICollection немного лучше, потому что он предоставляет свойство Count.

  • ListCollectionView - это тип представления, созданный, когда источник реализует IList. По сравнению с IEnumerable и ICollection, IList работает намного лучше для больших или динамических списков, поскольку он предоставляет индексатор, что позволяет нам быстро получить произвольный доступ. Кроме того, IList позволяет сортировать, группировать и фильтровать. Но в идеале ваша исходная коллекция происходит от ObservableCollection, матери всех коллекций в глазах привязки данных, поскольку она предоставляет несколько дополнительных полезных свойств, таких как уведомления об изменениях свойств и коллекции.

  • BindingListCollectionView - это тип представления, созданный Avalon, когда исходная коллекция реализует IBindingList. Это мнение, которое мы рассматриваем в сценарии ADO.NET. Он поддерживает сортировку и группировку, но не традиционную фильтрацию. Вместо этого у него есть дополнительное свойство CustomFilter, которое делегирует фильтрацию DataView (см. Мой пост в ADO.NET для более подробной информации).

Вы можете использовать фильтрацию для другого потока, как сказал @mihi, но я использовал CollectionViews для одновременного запуска нескольких фильтров на ObservableCollection с 50 000 элементов на объекте с ~ 60 переменными (столбцы в таблице базы данных) без заметного запаздывания.

Одна вещь, которую я сразу заметила в вашей функции фильтра, - это вход типа Object, который, вероятно, означает, что вы выполняете преобразование типа внутри функции, и, возможно, это не понадобится. Вы также используете Predicate, который не включает тип возвращаемого значения, поэтому, вероятно, потребуются некоторые преобразования типов или отражение в методах фильтрации CollectionView и может также замедлить вас.