WPF Datagrid Ленивая загрузка - PullRequest
8 голосов
/ 13 апреля 2011

Подробности

  1. VS-2008 Professional SP1
  2. Версия .net 3.5
  3. Язык: C #

У меня есть WPFDatagrid, который загружает из элемента данных Datacontext запроса Linq-sql. Результирующий набор содержит около 200 тыс. Строк и очень медленно загружает их, сортирует, фильтрует и т. Д. Каков простой и легкий способ повысить скорость?Пара вещей, которые я видел при поиске: Scrollview, виртуализация данных и т. Д., Люди также говорят о пейджинге, профилировании и т. Д.

Ответы [ 5 ]

4 голосов
/ 03 мая 2011

Загрузка данных: 200 тыс. Строк - это много данных, которые никто (пользователь) не хочет видеть в одном месте.Это определенно уменьшит ваш пользовательский интерфейс.Поэтому лучше всего фильтровать ваши данные только для того, чтобы уменьшить их объем (например, не показывать закрытые ордера, просто показывать открытые).Если вы не можете сделать это, вы должны использовать виртуализацию.Я не видел ни одного приложения, которое использует нумерацию страниц для отображения данных (конечно, кроме как в Интернете).В большинстве случаев это не очень хороший подход.Но если вы говорите о типе данных, которые похожи на результаты поисковых систем, вы должны использовать их.Но имейте в виду, что большинство пользователей не превысят страницу 10 в результатах поисковых систем.

Фильтрация: Я бы предложил сделать это на вашем сервере для такого огромного количества данных (SQLСервер здесь), или, как я уже сказал, сначала отфильтруйте целые 200 КБ, чтобы уменьшить количество на стороне сервера, а затем отфильтруйте его (для пользователя), чтобы найти что-то на стороне клиента.Также вам может пригодиться следующая ссылка:

  1. http://www.codeproject.com/KB/WPF/DataGridFilterLibrary.aspx

Сортировка: Снова я бы предложил решение сервер-клиент, но вы также можетеполезны следующие ссылки:

  1. http://blogs.msdn.com/b/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx
  2. http://blogs.msdn.com/b/jgoldb/archive/2008/08/28/improving-microsoft-datagrid-ctp-sorting-performance-part-2.aspx
  3. http://blogs.msdn.com/b/jgoldb/archive/2008/10/30/improving-microsoft-datagrid-sorting-performance-part-3.aspx

Многие люди не используютпо умолчанию SortMemberPath сетки данных WPF только потому, что она использует отражение для каждой отдельной записи, и это сильно снизит производительность процесса сортировки.

Hosein

1 голос
/ 14 июля 2011

Вот очень хороший пример виртуализации данных (не виртуализации пользовательского интерфейса):

http://www.codeproject.com/KB/WPF/WpfDataVirtualization.aspx

Хотя он не поддерживает объекты LINQ IQueryable напрямую, но вы можете использовать этот пример как есть. Конечно, я сейчас работаю над улучшением работы с объектами IQueryable напрямую. Я думаю, что это не так сложно.

0 голосов
/ 16 марта 2012

Иногда у вас может быть только ~ 30 видимых строк для загрузки, и если эти строки + какие-либо столбцы загружать дорого из-за их количества и сложности каждой ячейки (это шаблон или количество элементов wpf), ни один из вышеупомянутые комментарии действительно имеют значение. Каждая строка займет сладкое время для загрузки!

Что помогает, так это пошаговая или ленивая загрузка каждой строки в пользовательском интерфейсе, так что пользователь видит, что пользовательский интерфейс что-то делает, а не просто останавливается на ~ 10 + секунд. Для простоты предположим, что datagrid ItemSource = "{Binding Rows}" и Rows - это IEnumerable, где Row - это какой-то созданный вами класс: добавьте свойство IsVisible в Row (не забудьте поднять свойство измененное, конечно)

Вы могли бы сделать что-то вроде этого:

private void OnFirstTimeLoad()
{
    Task.Factory.StartNew(() =>
    {
        foreach (var row in ViewModel.Rows)                                                
        {
            /*this is all you really need, 
              note: since you're on the background thread, make sure IsVisible executes on the UI thread, my utils method does just that*/
              myUtils.ExecuteOnUiThread(() => row.IsVisible = true);

              /*optional tweak: 
              this just forces Ui to refresh so each row repaint staggers nicely*/
              Application.Current.Dispatcher
                         .Invoke(DispatcherPriority.Background, (SendOrPostCallback) delegate { }, null);
         }
       });
}

о, и не забудьте запустить в XAML:

<DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={StaticResource BoolToVisibility}}"/>
      ........
0 голосов
/ 03 мая 2011

Вопрос, который вы должны задать:

  1. Готовы ли пользователи просматривать 200К строк данных?
  2. Сколько данных слишком много для пользователей? Может предупредить пользователя, что запрос вернул слишком много строк, и вы перечисляете первые 1000
  3. Стоит ли тратить время и деньги на программирование страниц, виртуализацию данных и т. Д., Если пользователи не выходят за пределы первых 1000 строк.
0 голосов
/ 13 апреля 2011

Ух, 200К строк - это много данных. Пейджинг звучит как хорошая идея. Попробуйте решить, сколько строк на странице вы хотите, скажем, 50. При первом показе экрана показывайте только первые 50. Затем дайте пользователю возможность перемещаться между страницами.

Сортировка может быть сложнее, однако.

Виртуализация может быть еще одним вариантом, к сожалению, мне еще предстоит работать с виртуализацией.

...