Производительность WPF. Неправильный грязный прямоугольный расчет
В настоящее время я работаю над заданием клиента, связанным с проблемами производительности в приложении большого размера WPF-клиента.
Проблема в том, что приложение работает очень медленно / вяло. В частности, обработка таблиц данных (прокрутка, сортировка, выбор) чрезвычайно медленная и делает приложение непригодным для использования.
Я проанализировал состояние системы, когда одна вкладка, содержащая несколько текстовых полей, комбинированных списков и ярлыков, открыта и оставлена без работы (в ожидании ввода пользователя).
Вот мои выводы:
- Весь рендеринг рассчитан на GPU
- Здесь нет таких сложных функций, как анимация, растровые эффекты, прозрачность и т. Д.
- Когда вкладка находится в режиме ожидания (только курсор мигает в сфокусированном текстовом поле, остальная часть вкладки является статической и даже не содержит никаких данных), графический процессор работает до 90%
- GPU падает до 0 всякий раз, когда вкладка теряет фокус
- Процент GPU напрямую связан с размером окна. Небольшое окно снижает его до нескольких процентов, в полноэкранном режиме - почти до 100%.
- WPF Perforator говорит мне, что WPF вычисляет грязную область для всей вкладки, а не только мигающий курсор
- WPF Perforator сообщает о грязных прямоугольных обновлениях, превышающих 20/ сек на вкладке ожидания, и они напрямую связаны с использованием графического процессора
Мой вывод: во время разработки было введено много пользовательского кода (макет, обработка событий и т. Д.), Чтобы приспособить WPF к управляемой бэкэндом архитектуре системы в целом. Я предполагаю, что из-за некоторого пользовательского кода механизм грязного прямоугольника WPF был сломан. Это приводит к чрезмерной активности при рисовании и, следовательно, к высокому использованию графического процессора. Эти ненужные действия приводят к проблемам, описанным выше.
Теперь я ищу любой совет, где я должен начать свое расследование. Или, другими словами: Какие типичные ошибки могут совершать разработчики, чтобы нарушить алгоритм обновления грязного прямоугольника WPF. Любой вклад высоко ценится.
Большое спасибо и лучшие пожелания!
Manuel
1 ответ
Спасибо за вклад. Позвольте мне уточнить бэкэнд-ориентированный: пользовательский интерфейс очень динамичный. Сообщение от бэкэнда определяет структуру пользовательского интерфейса и отображаемые данные. Поэтому у нас нет xaml для структуры вкладок, только C#.
А пока я могу решить проблему. Я использовал Snoop и свернул каждый элемент один за другим, наблюдая за использованием графического процессора. Я обнаружил, что на одной из границ был очень маленький эффект пиксель-шейдера (DropShadowEffect). Как только я убрал эффект, графический процессор упал с 80% до 1%. WPF рисовал правильные грязные прямоугольники над небольшими частями пользовательского интерфейса. Проблема решена, дело закрыто.
Вещи, которые кажутся мне интересными: 1. Огромное влияние, которое этот небольшой эффект оказывает на использование графического процессора. 2. Это нарушает грязно-прямой расчет. 3. Так как это был не BitmapEffect, а PixelshaderEffect, я не смог раскрыть его, отключив BitmapEffects в Perforator.
Спасибо! М.М.