一般来说,我对资源字典和合并字典有一个问题,特别是在资源查找性能方面。经过一些性能测试后,我发现ResourceDictionary.get_MergedDictionaries是命中率最高的调用(在ANTS分析器中检查)。我们有大约300个资源字典xamls,其中很多都使用合并字典来“包含”其他样式。在我们的应用程序的一部分上,get_MergedDictionaries的点击量大约是1000万次,而在那里并没有发生太多事情。所以我的猜测是,我们对资源字典做了一些完全错误的事情。所以我试着重构所有的东西,我想摆脱所有合并的字典。
现在来看实际的问题。我试着摆脱合并字典,但我失败了。我的理解是,当您使用StaticResource时,查找需要在当前资源之前定义资源。我做了以下简短的例子:
一个主项目和一个自定义控件库。
自定义控件库包含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中添加一个合并字典并引用Colors.xaml,但我总是认为,我从来没有真正检查过,资源是根据逻辑树和元素的资源来查找的。我的理解是;创建了Button;尝试查找模板..找到了;尽量查找颜色,找不到自己的资源,走上去使用windows资源。
看来我错了。因此,我希望有人能为我提供一些启发。我们大量使用WPF,尽管如此,我们用它完成了很多工作,但由于一开始的一些错误的学习行为,仅仅因为资源查找,我们的性能就相当糟糕。任何帮助都将不胜感激
提前感谢,向Nico致以最好的问候
发布于 2011-07-29 18:27:24
好吧,我不喜欢回答我自己的问题,但我猜很多人可能会遇到这个问题,我想给他们我们目前的解决方案作为一个选择来考虑。
就像我之前说过的,我们有很多XAML,大约300左右用于所有不同种类的东西,比如共享资源(画笔,颜色),但也有许多XAML包含不同的DataTemplates,样式用于控件和自定义控件。在一开始,这种拥有大量XAML的方法对我们来说是合理的,因为我们对我们的类做了同样的事情,并使它们保持小而有组织。不幸的是,WPF并不喜欢这样。你拥有的ResourceDictionaries越多,你通过MergedDictionaries合并它们的次数越多,你的性能就会变得越差。我能给你的最好的建议是,使用尽可能少的ResourceDictionary XAML。
我们咬紧牙关,将它们中的许多合并成一个巨大的XAML,事实上,我们现在这样做是通过预编译器保持了这两个世界的最好。我们可以使用任意多的XAML,只需遵循几个约束,然后在编译器上将它们合并成一个巨大的XAML。我们得到的性能提升是显著的。在我的问题中,我写了“getMergedDictionaries上有1100万的点击量”...仅仅是“预编译”我们的一个程序集,我们的点击量就降到了200万次,整个应用程序的性能在任何时候都要好得多。
所以最后。XAML资源不应该被认为是经过编译的源代码,相反,它应该被理解为一个实际的资源,当声明存在时,它会占用空间和性能。
好吧,我们必须通过艰难的方式来学习。我希望每个阅读这篇文章的人都能通过从我们的错误中学习来改进他们的项目。
发布于 2012-01-06 01:08:23
我倾向于在一个应用程序中只使用一个ResourceDictionary来避免任何性能问题。
为了保持XAML的可管理性,我使用了XAML regions Visual Studio插件并将每一类资源包装在一个区域中。
在这种情况下,插件绝对是救命稻草。http://visualstudiogallery.msdn.microsoft.com/3c534623-bb05-417f-afc0-c9e26bf0e177
发布于 2011-08-05 19:39:41
使用SharedResourceDictionary而不是ResourceDictionary完全解决了我的MergedDictionaries性能问题:http://www.wpftutorial.net/MergedDictionaryPerformance.html
https://stackoverflow.com/questions/6693320
复制相似问题