Udostępnij za pośrednictwem


Optymalizacja wydajności: zasoby aplikacji

Platforma WPF umożliwia udostępnianie zasobów aplikacji, dzięki czemu można obsługiwać spójny wygląd lub zachowanie między podobnymi elementami. Ten temat zawiera kilka zaleceń w tym obszarze, które mogą pomóc w zwiększeniu wydajności aplikacji.

Aby uzyskać więcej informacji na temat zasobów, zobacz Zasoby XAML.

Udostępnianie zasobów

Jeśli aplikacja używa kontrolek niestandardowych i definiuje zasoby w węźle ResourceDictionary (lub zasoby XAML), zaleca się zdefiniowanie zasobów na Application poziomie obiektu lub Window lub zdefiniowanie ich w motywie domyślnym dla kontrolek niestandardowych. Definiowanie zasobów w kontrolce ResourceDictionary niestandardowej nakłada wpływ na wydajność dla każdego wystąpienia tej kontrolki. Jeśli na przykład masz operacje pędzla intensywnie korzystające z wydajności zdefiniowane w ramach definicji zasobu niestandardowej kontrolki i wiele wystąpień kontrolki niestandardowej, zestaw roboczy aplikacji znacznie się zwiększy.

Aby zilustrować ten punkt, rozważ następujące kwestie. Załóżmy, że opracowujesz grę kartową przy użyciu WPF. W przypadku większości gier kartowych potrzebujesz 52 kart z 52 różnymi twarzami. Decydujesz się zaimplementować kontrolkę niestandardową karty i definiujesz 52 pędzle (z których każda reprezentuje twarz karty) w zasobach kontrolki niestandardowej karty. W głównej aplikacji początkowo utworzysz 52 wystąpienia tej kontrolki niestandardowej karty. Każde wystąpienie kontrolki niestandardowej karty generuje 52 wystąpienia Brush obiektów, co daje łącznie 52 * 52 Brush obiekty w aplikacji. Przenosząc pędzle z zasobów kontrolki niestandardowej karty do Application poziomu obiektu lub Window lub definiując je w domyślnym motywie kontrolki niestandardowej, można zmniejszyć zestaw roboczy aplikacji, ponieważ teraz udostępniasz 52 pędzle wśród 52 wystąpień kontrolki karty.

Udostępnianie pędzla bez kopiowania

Jeśli masz wiele elementów korzystających z tego samego Brush obiektu, zdefiniuj szczotkę jako zasób i odwołaj się do niego, zamiast definiować pędzl w tekście w języku XAML. Ta metoda utworzy jedno wystąpienie i użyje go ponownie, podczas gdy definiowanie pędzli wbudowanych w języku XAML tworzy nowe wystąpienie dla każdego elementu.

Poniższy przykład znaczników ilustruje ten punkt:

<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>

Użyj zasobów statycznych, gdy jest to możliwe

Zasób statyczny udostępnia wartość dla dowolnego atrybutu właściwości XAML, wyszukując odwołanie do już zdefiniowanego zasobu. Zachowanie wyszukiwania dla tego zasobu jest analogiczne do wyszukiwania w czasie kompilacji.

Z drugiej strony zasób dynamiczny utworzy wyrażenie tymczasowe podczas początkowej kompilacji, a tym samym odroczyć wyszukiwanie zasobów do momentu, gdy żądana wartość zasobu będzie rzeczywiście wymagana w celu utworzenia obiektu. Zachowanie wyszukiwania dla tego zasobu jest analogiczne do wyszukiwania w czasie wykonywania, co nakłada wpływ na wydajność. Używaj zasobów statycznych zawsze, gdy jest to możliwe w aplikacji, używając zasobów dynamicznych tylko wtedy, gdy jest to konieczne.

W poniższym przykładzie znaczników przedstawiono użycie obu typów zasobów:

<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>

Zobacz też