| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > WPF и Silverlight > WPF. Тормоза анимации. Неясны причины |
| Автор: AleksPingvin 5.1.2012, 14:45 | ||
| Долго я мучался, но так как не смог найти решения спрашиваю вас, дорогие друзья. Начнем с того, что имеется: есть клиентский компьютер с двумя видеокартами и 4-мя FullHD мониторами. На каждый монитор выводится список с тяжеловесными итемами (много прозрачностей, таблицы в собственных контейнерах и т.п.) Каждый список должен скролироваться от итема к итема, с заданным периодом, при этом их высота может меняться со временем, или они могут вообще исчезать. Проблема: скролинг должен быть карусельный. До этого был ListBox у которого анимировался ScrollViewer через DependencyProperties которое изменяло ScrollVerticalOffset и впринципе все более-менее сносно ползало с 25% загрузкой CPU. Поскольку поступила задача оптимизировать расход ЦПУ и сделать карусель, то листбокс был выкинут и создан собственный класс, код которого представлен ниже. Так вот - анимация стала гораздо тормозней, хотя загрузка CPU не превышает 2-5%.
Вопрос как всегда простой - почему и что делать? |
| Автор: Gvozdin 5.1.2012, 17:57 |
| 1. используйте профайлер что бы посмотреть куда тратиться процессорное время 2. код контрола на первый взгляд нормальный, только непонятно зачем устанавливать Clip 3. ответ тоже как всегда, давайте солюшн с воспроизведением, в процессе может и сами все решите |
| Автор: AleksPingvin 8.1.2012, 12:10 |
| Прогнал профайлером на требуемой конфигурации, которая будет стоять у клиента и на более мощной тачке (на ней кстати тормозов нет), итог таков: На слабой машине время выполнения ArrangeOverride = 13 ms, на мощной - 1,5 ms. Я к несчастью не знаю как реализован ScrollViewer, но по видимому он не вызывает Arrange у контейнера (во всяком случае в ListBox-е), ибо в случае с ним на слабой машине нет тормозов. Если это так, то я не могу представить не тормозную версию карусели. Обычно такие вещи не в wpf я делал так: брал холст равный двойной высоте от требуемой, рендерил итема на него, два раза, и дальше путем Clip-инга выводил все это куда-то. Но тут же так нельзя, я ведь не могу два раза отрендерить Сhild в разные места. Есть идея выводить не тяжеловесные контейнеры, а их битмапы (я пробовал BitmapCached - не могло), но это сложно очень в реализации, ибо итема могут менять свои размеры в процессе анимации. Есть идеи? |
| Автор: Gvozdin 8.1.2012, 20:00 |
| 1. Для отрисовки картинок вместо айтемов посмотрите http://blogs.msdn.com/b/kaelr/archive/2008/06/18/snapshooter.aspx 2. 15ms это время одного выполнения ArrangeOverride у вашего контрола? Если это так то это как-то медленно, оптимизируйте 3. Оптимизируйте работу контрола в общем, посмотрите 3.a что бы небыло лишних и повторных вызовов MeasureOverride, как вашего контрола так и айтемов 3.b аналогично что бы не было непонятных вызовов ArrangeOverride Вы ведь сами управляете анимацией и знаете когда должны происходить вызовы Measure и когда Arrange. Вставьте трассировку и смотрите что бы все было как вы хотите. |
| Автор: AleksPingvin 9.1.2012, 09:08 |
| Буду смотреть... думать.... спасибо за ответы! |