Ленивая загрузка WPF Datagrid

подробности

  1. VS-2008 профессиональный SP1
  2. версия .net 3.5 с
  3. Язык:C#

У меня есть WPF Datagrid, который загружается из элемента данных Datacontext запроса Linq-sql.Результирующий набор содержит около 200k строк и его очень медленная загрузка, сортировка,фильтрация и т. д. Что такое простой и легкий способ улучшить скорость?

пара вещей, которые я видел в поиске Scrollview, виртуализация данных и т. д. Люди также говорят о Подкачки,профилирования и т. д.

5 ответов


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

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

  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

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

Хосейн


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

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

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


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

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

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


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

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

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

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}}"/>
      ........

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

  1. пользователи groing, чтобы просмотреть 200K строк данных?
  2. объем данных слишком много для пользователей? Может предупредить пользователя, что запрос вернул слишком много строк и вы перечисляете первые 1000
  3. стоит ли ваше время и деньги для программирования подкачки, виртуализации данных и т. д., Если пользователи не выходят за пределы первых 1000 строк.