WPF: медленная реализация шаблона - PullRequest
23 голосов
/ 26 апреля 2011

У меня есть приложение WPF, и оно медленно.

Это НЕ рендеринг.Во-первых, рендеринг довольно прост, а во-вторых, я посмотрел на него с WPF Performance Toolkit - ничего.

Это НЕ в моем собственном коде.Во-первых, модульные тесты работают быстро, а во-вторых, если я заменю все шаблоны данных на пустые, все будет работать быстро.

Пока что похоже, что медленная часть - это создание шаблона .То есть, когда вы запускаете приложение и открываете какой-то сложный экран, это занимает много времени.И под " много " я имею в виду " много ".Иногда может достигать 3-5 секунд, например, когда существует сетка данных со 100 строками.Но когда вы переходите на другую вкладку, а затем возвращаетесь к тому же экрану, он открывается быстро (пока его viewmodel остается на месте).

Это очень раздражает не только потому, что он медленный, но и потому, что я могуничего не поделать.Если бы у меня был некоторый контроль над медлительностью, я мог бы, возможно, отобразить какое-нибудь сообщение ", пожалуйста, подождите " или что-то в этом роде ...

Кроме того, когда я смотрю на некоторые другие приложения WPF(прежде всего ILSpy), они, кажется, работают достаточно быстро, несмотря на большие объемы данных.Это заставляет меня поверить, что я, вероятно, делаю что-то не так.Но я понятия не имею, с чего начать.

Есть идеи?Есть классические ошибки?Любые советы?

Ответы [ 5 ]

5 голосов
/ 05 мая 2011

Мой опыт связан с работой над приложением WPF для отображения разума NovaMind

Пару месяцев назад мы полностью переписали наш промежуточный уровень для решения проблем производительности, с которыми мы столкнулись.В двух словах, создание наших пользовательских элементов управления казалось медленным.К сожалению, я не смог найти отличный способ для профилирования производительности, поскольку ни WPF Performance Suite, ни коммерческие приложения, такие как ANTS Profiler, не дают вам подробной информации об этой части процесса WPF.(Я задал этот вопрос тогда)

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

В итоге мы решили проблемы с производительностью, полностью переписав наши элементы управления.Мы также значительно сократили сложность нашего визуального дерева.До переписывания один из наших наиболее часто используемых пользовательских элементов управления при проверке с помощью Snoop состоял из 61 различных элементов, теперь их всего 3. По возможности, мы добавляли элементы в визуальное дерево только по требованию.(Как вы знаете в XAML, даже когда вы устанавливаете вещи в Collapsed, они должны быть созданы в первую очередь).Наконец, мы были вынуждены написать наш собственный элемент управления отображением расширенного текста, так как встроенный RichtextBox смехотворно медленный, а визуальное дерево RichtextBox довольно сложное.

Я не знаю, будет ли это применяться в вашей ситуации, ноЯ бы порекомендовал вам изучить ваши пользовательские элементы управления и посмотреть, являются ли они сложными.Может быть, у вас есть вещи, которые вы могли бы обрезать.Низко висящие фрукты - это части, которые редко видны или могут быть созданы ленивым образом.Вы можете создавать эти части из кода, когда это необходимо, вместо того, чтобы использовать их в XAML.Это должно вам очень помочь.

В противном случае виртуализация станет вашим другом, если это возможно.В нашем случае, к сожалению, мы не смогли этого сделать.

2 голосов
/ 18 мая 2012

Это похоже на проблему, с которой я столкнулся. Я разместил исправление здесь: Проблема автоматизации пользовательского интерфейса WPF . Просто публикуйте сообщения в поисковиках, так как для их решения потребовались годы.

После комментария на ссылку только ответ, вот суть этого поста:

Я сделал следующее:

  1. Загруженное исправление - - http://archive.msdn.microsoft.com/KB978520 (может не потребоваться)
  2. Загруженное исправление - - http://archive.msdn.microsoft.com/KB2484841 (обязательно, даже если у вас Windows 7 / .NET 4)
  3. Дальнейшее улучшение кода (проверка приводила к избытку объектов) - Почему WPF Style для отображения ошибок проверки в ToolTip работает для TextBox, но не работает для ComboBox?

Может быть, требовался только номер 3, но он работал. Просто публикуйте здесь, чтобы люди не теряли дни, которые я потерял в профайлерах памяти и т. Д.

1 голос
/ 06 мая 2011

Вы упоминаете, что используете DataGrid со, скажем, 100 строками. Вероятным виновником ваших проблем с перфорированием является то, что используемая вами сетка данных не выполняет виртуализацию, и поэтому ваше визуальное дерево гигантское.

Обычно длительное время запуска на экранах WPF указывает на большое визуальное дерево.

Я не уверен, используете ли вы табличку данных для каждой строки или какую-то стороннюю сетку, которая связывает столбцы, или что - но допустим, у вас есть 8 столбцов с элементами управления. В зависимости от вашей сетки / проверки / и т. Д., Это может быть визуальное дерево из 20-60 элементов в строке . Если у вас есть выпадающий список, то каждый элемент в раскрывающемся списке может быть создан также для каждой строки.

Чтобы исправить это, нужно просто посмотреть детали и принять меры:

  1. Максимально используйте виртуализированный элемент управления. Это означает использование виртуальной панели стека в элементах управления списком и обеспечение того, чтобы ваши сторонние элементы управления работали так же (многие стандартные элементы управления WPF теперь делают по умолчанию)
  2. Не злоупотребляйте пользовательскими элементами управления, составными элементами управления и т. Д. Добавление глубины увеличивает время, а добавление дополнительной глубины визуального дерева в табличку данных или другую повторяющуюся область быстро складывает.
  3. Если ничего не помогает, покажите простой экран и добавьте элементы управления с помощью кода, чтобы улучшить воспринимаемую производительность
1 голос
/ 05 мая 2011
  • Попробуйте переместить все ресурсы вверх как насколько они пойдут, желательно в App.xaml
  • Проверьте, можете ли вы использовать StaticResource вместо динамических, статических намного быстрее
  • Если возможно, попробуйте использовать зависимость свойства в ваших виртуальных машинах, особенно если у вас есть много из них сразу или если у них много свойств. Это избавит wpf от необходимости размышлять.
1 голос
/ 05 мая 2011

Пользовательский контроль в вашем шаблоне данных, не совсем плохая идея, но если вы стремитесь к производительности, то вам следует подумать о переходе на более легкий контроль.Например, иметь UserControl, просто размещающий TextBox, очень плохая идея, так как UserControl состоит из ContentControl, ContentControl размещает ContentPresenter, а ContentPresenter будет размещать TextBox, поэтому, если вы заметите свое Visual Tree, у него будет три новых слоя элементов пользовательского интерфейса.Сокращение Visual Tree, безусловно, улучшит производительность.

Скорее всего, я бы предложил создать пользовательские элементы управления, которые могут быть совершенно новым элементом управления, имеющим несколько свойств зависимостей, которые могут относиться к данным, которые вы хотите представить, и вы можете иметь ихсобственный настраиваемый шаблон в generic.xaml.Во-вторых, вы можете просто извлечь элемент управления из существующих элементов управления и переопределить его шаблон по умолчанию в generic.xaml.

Этот подход, безусловно, будет работать лучше, так как вы будете сокращать свое визуальное дерево, тем самым сокращая работу диспетчера визуальных состояний.

Изменение темы или шаблона будет выполняться медленнее, чем изменение элемента, на котором размещается контент.И пусть элемент имеет шаблон по умолчанию в своем собственном словаре общих ресурсов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...