共用方式為


最佳化效能:應用程式資源

WPF 可讓您共用應用程式資源,以便在跨相似類型的元素時能支援一致的外觀或行為。 本主題針對這方面提供一些建議,可協助您改善應用程式的效能。

如需詳細資訊,請參閱 XAML 資源

資源分享

如果您的應用程式使用自訂控制項,並在 ResourceDictionary (或 XAML 資源節點) 中定義資源,建議您在 ApplicationWindow 物件層級定義資源,或在自訂控制項的預設主題中定義資源。 定義自訂控制項 ResourceDictionary 中的資源會對該控制項控件的每個執行個體造成效能影響。 例如,如果您的效能密集型筆刷作業定義為自訂控制項的資源定義的一部分和自訂控制項的許多執行個體,則應用程式的工作集將會大幅增加。

若要說明這一點,請考慮下列內容。 假設您正在開發使用 WPF 的卡牌遊戲。 對於大部分的卡牌遊戲,您需要 52 張有 52 個不同花色的卡片。 您決定實作卡牌自訂控制項,並在卡牌自訂控制項的資源中定義 52 個筆刷 (每個筆刷都代表卡牌花色)。 在主要應用程式中,您一開始會建立此卡牌自訂控制項的 52 個執行個體。 卡牌自訂控制項的每個執行個體都會產生 52 個 Brush 物件的執行個體,讓您在應用程式中總共有 52 * 52 個 Brush 物件。 藉由將筆刷移出卡牌自訂控制項資源至 ApplicationWindow 物件層級,或在自訂控制項的預設主題中定義筆刷,即可減少應用程式的工作集,因為您現在在卡牌控制項的 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>

另請參閱