23

特にリソースルックアップのパフォーマンスに関しては、リソースディクショナリとマージディクショナリ全般に問題があります。いくつかのパフォーマンステストの結果、ResourceDictionary.get_MergedDictionariesが最もヒット数の多い呼び出しであることがわかりました(ANTSプロファイラーでチェック済み)。約300のリソースディクショナリxamlsがあり、それらの多くは、他のスタイルを「含める」ためにマージされたディクショナリを使用しています。get_MergedDictionariesは、アプリケーションの一部で、あまり発生していない部分で、約1,000万ヒットでした。ですから、私の推測では、一般的にリソースディクショナリで完全に間違ったことをしているのです。だから私はすべてをリファクタリングしようとしました、そして私はすべてのマージされた辞書を取り除くことを試みたいです。

さて、実際の質問に移りましょう。マージディクショナリを削除しようとしましたが、失敗しました。私の理解では、StaticResourceを使用する場合、ルックアップでは現在のリソースの前にリソースを定義する必要があります。次の短い例を作成しました。

1つのメインプロジェクトと1つのカスタムコントロールライブラリ。

カスタムコントロールライブラリには2つのxamlsが含まれています。

<!-- Colors.xaml -->
<ResourceDictionary [stripped namespaces] >
    <SolidColorBrush x:Key="myColor" Color="Green"/>
</ResourceDictionary>

<!-- Templates.xaml -->
<ResourceDictionary [stripped namespaces]>
    <ControlTemplate x:Key="myTemplate" TargetType="Button">
        <Rectangle Fill="{StaticResource myColor}"/>
    </ControlTemplate>
</ResourceDictionary>

メインプロジェクトでは、MainWindow.xamlは次のようになります

<Window x:Class="ResourceTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/ResourceTestLib;component/Themes/Colors.xaml"/>
                <ResourceDictionary Source="/ResourceTestLib;component/Themes/Template.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Template="{StaticResource myTemplate}"/>
    </Grid>
</Window>

それが望ましい目標です。ただし、リソース「myColor」が見つからないため、残念ながらこれはクラッシュします。もちろん、それを修正する方法を知っています。Templates.xamlにmergeddictionaryを追加し、Colors.xamlを参照しますが、論理ツリーと要素のリソースに応じてリソースが検索されることを常に考えていました。私の理解は; ボタンが作成されます。テンプレートを検索してみてください..見つかりました; 自分のリソースでは見つからない色を検索し、上に移動してWindowsリソースを使用してみてください。

私は間違っているようです。だから私は誰かが私のためにこれにいくつかの光を当てることができることを願っています。WPFを多用し、それにもかかわらず多くのことを達成しましたが、最初に学習した動作が間違っていたため、リソースの検索だけでパフォーマンスがかなり悪くなりました。どんな助けでも大歓迎です

よろしくお願いしますニコ

4

4 に答える 4

52

ええと、私は自分の質問に答えるのは好きではありませんが、多くの人がこれに出くわす可能性があると思います.

前に言ったように、共有リソース (ブラシ、色) などのさまざまな種類のものだけでなく、さまざまな DataTemplates、コントロールのスタイル、およびカスタム コントロールを含む多くの XAML に約 300 の XAML があります。最初は、多くの XAML を使用するというこのアプローチは、私たちにとって合理的でした。なぜなら、クラスでも同じことを行い、クラスを小さく整理しておくためです。残念ながら、WPF はそれを好みません。ResourceDictionaries が増え、MergedDictionaries を介してそれらをマージすればするほど、パフォーマンスが低下します。私からできる最善のアドバイスは、使用する ResourceDictionary XAML をできるだけ少なくすることです。

私たちは弾丸をかじり、それらの多くを 1 つの巨大な XAML にマージしました。実際、現在、両方の長所を維持するプリコンパイラを使用してこれを行っています。いくつかの制約に従い、巨大な XAML でのコンパイル時にそれらをマージするだけで、必要な数の XAML を使用できます。私たちが得たパフォーマンスの向上は目覚ましいものでした。私の質問では、「getMergedDictionaries で 1,100 万回のヒット」と書きました...アセンブリの 1 つを「プリコンパイル」するだけで、200 万回のヒットになり、アプリケーション全体のパフォーマンスは常にずっと良くなりました。

最後に。XAML リソースは、コンパイルされるソース コードと見なされるべきではありません。代わりに、宣言されたときに存在し、スペースとパフォーマンスを占有する実際のリソースとして理解する必要があります。

まあ、私たちはそれを難し​​い方法で学ばなければなりませんでした。これを読んでいるすべての人が、私たちの過ちから学ぶことでプロジェクトを改善できることを願っています。

于 2011-07-29T10:27:23.620 に答える
3

パフォーマンスの問題を回避するために、アプリケーションで ResourceDictionary を 1 つだけ使用する傾向があります。

XAML を管理しやすくするために、XAML リージョン Visual Studio プラグインを使用し、リソースの各カテゴリをリージョンにラップします。

  • ブラシ
  • テキスト スタイル
  • 等...

このシナリオでは、プラグインは絶対的な命の恩人です。 http://visualstudiogallery.msdn.microsoft.com/3c534623-bb05-417f-afc0-c9e26bf0e177

于 2012-01-05T17:08:23.127 に答える
1

ResourceDictionaryの代わりにSharedResourceDictionaryを使用すると、MergedDictionariesのパフォーマンスの問題が完全に解決されました: http ://www.wpftutorial.net/MergedDictionaryPerformance.html

于 2011-08-05T11:39:40.623 に答える
0

リソース検索手順に光が当てられましたか?「myColor」が見つからなかったのはなぜですか?

ちなみに、私はそれを機能させる方法を見つけましたが、奇妙で不安定な方法です。Application.xamlにこのコードがある場合、色は次のようになります。

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/ResourceTestLib;component/Themes/Colors.xaml"/>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/ResourceTestLib;component/Themes/Template.xaml"/> 
        </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary>
</ResourceDictionary.MergedDictionaries>

一方、このコードを別のXAMLに含め、それをApplication.xamlに含めると、リソース構造が同一であっても機能しません(Snoopで確認済み)。

于 2012-07-12T12:37:37.097 に答える