Оптимизация производительности: ресурсы приложения

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

Дополнительные сведения о ресурсах см. в разделе Ресурсы XAML.

Совместное использование ресурсов

Если приложение использует пользовательские элементы управления и определяет ресурсы в ResourceDictionary (или узле ресурсов XAML), рекомендуется определить ресурсы на уровне объекта Application или Window либо определить их в теме по умолчанию для пользовательских элементов управления. Определение ресурсов в пользовательском элементе управления ResourceDictionary влияет на производительность каждого экземпляра этого элемента управления. Например, если у вас есть высокопроизводительные операции кисти, определенные как часть определения ресурса пользовательского элемента управления и несколько экземпляров пользовательского элемента управления, рабочий набор приложения значительно увеличится.

Чтобы лучше проиллюстрировать это, рассмотрим следующий код. Предположим, вы разрабатываете карточные игры с помощью WPF. Для большинства карточных игр вам потребуется 52 карты с 52 разными рисунками на лицевой стороне. Вы решили реализовать пользовательский элемент управления карточки и определить 52 кисти (каждый из которых представляет лицевую сторону карты) в ресурсах пользовательского элемента управления для карты. В основном приложении изначально создается 52 экземпляра этого пользовательского элемента управления для карты. Каждый экземпляр пользовательского элемента управления карточки создает 52 экземпляра объектов Brush, что дает вам в общей сложности 52 * 52 объектов Brush в приложении. Переместив кисти из ресурсов пользовательского элемента управления для карты на уровень объекта Application или Window либо определив их в теме по умолчанию для пользовательского элемента управления, можно уменьшить рабочий набор приложения, так как теперь вы предоставляете общий доступ к 52 кистям для 52 экземпляров элемента управления карты.

Совместное использование кисти без копирования

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

Это показано в следующем примере разметки.

<StackPanel.Resources>
  <LinearGradientBrush x:Key="myBrush" StartPoint="0,0.5" EndPoint="1,0.5" Opacity="0.5">
    <LinearGradientBrush.GradientStops>
      <GradientStopCollection>
        <GradientStop Color="GoldenRod" Offset="0" />
        <GradientStop Color="White" Offset="1" />
      </GradientStopCollection>
    </LinearGradientBrush.GradientStops>
  </LinearGradientBrush>
</StackPanel.Resources>

<!-- Non-shared Brush object. -->
<Label>
  Label 1
  <Label.Background>
    <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5" Opacity="0.5">
      <LinearGradientBrush.GradientStops>
        <GradientStopCollection>
          <GradientStop Color="GoldenRod" Offset="0" />
          <GradientStop Color="White" Offset="1" />
        </GradientStopCollection>
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Label.Background>
</Label>

<!-- Shared Brush object. -->
<Label Background="{StaticResource myBrush}">Label 2</Label>
<Label Background="{StaticResource myBrush}">Label 3</Label>

Использование статических ресурсов по возможности

Статический ресурс предоставляет значение для любого атрибута свойства XAML путем поиска ссылки на уже определенный ресурс. Поведение поиска для этого ресурса аналогично поиску во время компиляции.

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

В следующем примере разметки демонстрируется использование обоих типов ресурсов.

<StackPanel.Resources>
  <SolidColorBrush x:Key="myBrush" Color="Teal"/>
</StackPanel.Resources>

<!-- StaticResource reference -->
<Label Foreground="{StaticResource myBrush}">Label 1</Label>

<!-- DynamicResource reference -->
<Label Foreground="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">Label 2</Label>

См. также