Оптимизация производительности: Поведение объекта
Понимание внутреннего поведения объектов WPF поможет найти оптимальное сочетание функциональных возможностей и производительности.
Не удаление обработчиков событий для объектов может поддерживать объекты в активном состоянии
Делегат, который объект передает в свое событие, фактически является ссылкой на этот объект. Таким образом, обработчики событий могут поддерживать объекты в активном состоянии дольше, чем планировалось. При выполнении очистки объекта, зарегистрированного для прослушивания события объекта, необходимо удалить этот делегат перед освобождением объекта. Сохранение ненужных объектов в активном состоянии увеличивает потребление памяти. Это особенно важно в тех случаях, когда объект является корневым элементом логического дерева или визуального дерева.
WPF предоставляет шаблон прослушивателя слабых событий для событий, которые могут быть полезны в ситуациях, когда трудно отслеживать отношения между источником и прослушивателем во время существования объекта. Некоторые существующие события WPF используют этот шаблон. При реализации объектов с пользовательскими событиями этот шаблон может вам пригодиться. Дополнительные сведения см. в разделе Шаблоны слабых событий.
Существует несколько инструментов, таких как профилировщик CLR и Working Set Viewer, которые могут предоставлять сведения об использовании памяти указанным процессом. Профилировщик CLR включает ряд очень полезных представлений профиля выделения, включая гистограмму выделенных типов, диаграммы выделения и вызова, временную шкалу, показывающую сборку мусора разных поколений и итоговое состояние управляемой кучи после этих сборок, а также дерево вызовов, показывающее распределения по методам и загрузки сборок. Дополнительные сведения см. в разделе Центр разработчиков .NET Framework.
Свойства и объекты зависимостей
Как правило, доступ к свойству зависимостей из Dependency
Оптимизация DependencyProperty
Свойства зависимостей в приложении следует определять очень внимательно. Если ваш Dependency
Возможно, более рационально использовать обработчик изменений свойств, чтобы аннулировать передачу размера, упорядочения и отображения вручную, если не все изменения свойств фактически влияют на размер, упорядочение и отображение. Например, вы можете решить заново отображать фон, только когда значение выше установленного ограничения. В этом случае обработчик изменений свойств будет аннулировать отображение, только когда значение превышает установленное ограничение.
Наследуемость DependencyProperty не обходится даром
По умолчанию зарегистрированные свойства зависимостей не являются наследуемыми. Тем не менее вы можете явно сделать любое свойство наследуемым. Хотя это полезная возможность, преобразование свойства в наследуемое негативно влияет на производительность, увеличивая интервал времени для аннулирования свойства.
Используйте RegisterClassHandler с осторожностью
Во время вызова методов Register
Установка значения по умолчанию для DependencyProperty во время регистрации
При создании Dependency
Установка значения PropertyMetadata с помощью реестра
При создании Dependency
Объекты Freezable
Объект Freezable — это специальный тип объекта, имеющий два состояния: фиксированное и нефиксированное. Фиксация объектов везде, где это возможно, улучшает производительность приложения и уменьшает его рабочий набор. Дополнительные сведения см. в разделе Общие сведения об объектах класса Freezable.
Каждый Freezable имеет Changed событие, возникающее при каждом его изменении. Однако уведомления об изменениях обходятся дорого с точки зрения производительности приложения.
Рассмотрим следующий пример, в котором каждый Rectangle использует тот же Brush объекта:
rectangle_1.Fill = myBrush;
rectangle_2.Fill = myBrush;
rectangle_3.Fill = myBrush;
// ...
rectangle_10.Fill = myBrush;
По умолчанию WPF предоставляет обработчик событий для Solid
Замораживание Freezable позволяет повысить его производительность, поскольку он больше не требуется тратить ресурсы на уведомления об изменениях. В следующей таблице показан размер простого объекта Solidtrue
, если он недопустим по сравнению с. Это предполагает применение одной кисти к Fill свойство десяти Rectangle объектов.
Регион | Размер |
---|---|
FROZEN Solid |
212 байт |
Нефиксированный Solid |
972 байта |
Следующий пример кода демонстрирует эту концепцию.
Brush frozenBrush = new SolidColorBrush(Colors.Blue);
frozenBrush.Freeze();
Brush nonFrozenBrush = new SolidColorBrush(Colors.Blue);
for (int i = 0; i < 10; i++)
{
// Create a Rectangle using a non-frozed Brush.
Rectangle rectangleNonFrozen = new Rectangle();
rectangleNonFrozen.Fill = nonFrozenBrush;
// Create a Rectangle using a frozed Brush.
Rectangle rectangleFrozen = new Rectangle();
rectangleFrozen.Fill = frozenBrush;
}
Обработчики событий изменений Changed в нефиксированных объектах Freezable могут поддерживать объекты в активном состоянии
Делегат, который объект передает в Freezable объекта Changed событий является ссылкой на этот объект. Таким образом Changed обработчики событий могут поддерживать объекты в активном состоянии больше, чем ожидалось. При выполнении очистки объекта, зарегистрированного для прослушивания Freezable объекта Changed событий, очень важно удалить этот делегат перед освобождением объекта.
WPF также подключает Changed события внутренним образом. Например, все свойства зависимостей принимающие Freezable как значение будет прослушивать Changed события автоматически. Fill Свойство, которое принимает Brush, иллюстрирует эту концепцию.
Brush myBrush = new SolidColorBrush(Colors.Red);
Rectangle myRectangle = new Rectangle();
myRectangle.Fill = myBrush;
При назначении myBrush
для myRectangle.Fill
делегат, указывающий обратно Rectangle добавляется объект SolidmyRect
сборку мусора.
myRectangle = null;
В этом случае myBrush
по-прежнему сохраняет myRectangle
активном состоянии и снова вызовет его при его срабатывании его Changed событий. Обратите внимание, что при назначении myBrush
для Fill свойства нового Rectangle будет просто добавляться другой обработчик событий в myBrush
.
Рекомендуемый способ очистки этих типов объектов должно быть удаление Brush из Fill свойство, которое в свою очередь приведет к удалению Changed обработчик событий.
myRectangle.Fill = null;
myRectangle = null;
Виртуализация пользовательского интерфейса
WPF также предоставляет разновидность Stack
Для оптимизации производительности визуальные объекты для этих элементов создаются или поддерживаются в активном состоянии, только если они будут отображаться на экране. Если они больше не находятся в видимой области элемента управления, визуальные объекты могут быть удалены. Это не следует путать с виртуализацией данных, где не все объекты данных присутствуют в локальной коллекции, а скорее, передаются в потоке при необходимости.
В следующей таблице показано затраченное время, добавление и отрисовку 5000 Text
Главная панель | Время отрисовки (мс) |
---|---|
Stack |
3210 |
Virtualizing |
46 |