【发布时间】:2011-10-11 20:52:24
【问题描述】:
我正在构建一个 WPF 桌面应用程序,它的 UI 虽然是动态的,但在我看来并不像它应该特别苛刻。此应用程序中的典型用户控件实现了一个包含两列网格的扩展器,其中一列包含标签,另一列包含文本框或组合框。扩展器内容的 XAML 如下所示:
<DockPanel Style="{StaticResource Style_ExpandedGridRowView}"
Focusable="False">
<DockPanel.Resources>
<DataTemplate DataType="{x:Type vm:BooleanFieldViewModel}">
<local:GridBooleanField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ChoiceFieldViewModel}">
<local:GridChoiceField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CodeLookupFieldSingleSelectionViewModel}">
<local:GridCodeLookupField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CodeLookupFieldMultipleSelectionViewModel}">
<local:GridCodeLookupMultiSelectField DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CurrencyFieldViewModel}">
<local:GridCurrencyField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:DateFieldViewModel}">
<local:GridDateField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:NotesFieldViewModel}">
<local:GridNotesField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:NumberFieldViewModel}">
<local:GridNumberField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TextFieldViewModel}">
<local:GridTextField DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TimeFieldViewModel}">
<local:GridTimeField DataContext="{Binding}" />
</DataTemplate>
</DockPanel.Resources>
<AdornerDecorator>
<ItemsControl ItemsSource="{Binding Fields, Mode=Default}"
Focusable="False">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"
Grid.IsSharedSizeScope="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</AdornerDecorator>
</DockPanel>
我已经分析了我的视图模型,枚举 Fields 属性只需要不到 100 个滴答声,它包含的项目少于 15 个。
当我展开它时,展开器需要 20-30 秒 来呈现它的内容。
在此期间,应用程序完全没有响应。这将被写入输出窗口,大约每 4-5 秒一条消息:
The thread '<No Name>' (0x21b0) has exited with code 0 (0x0).
The thread '<No Name>' (0x1c54) has exited with code 0 (0x0).
The thread '<No Name>' (0x1c7c) has exited with code 0 (0x0).
The thread '<No Name>' (0x2638) has exited with code 0 (0x0).
The thread '<No Name>' (0x1bf0) has exited with code 0 (0x0).
内容最终呈现后,我可以毫无延迟地打开和关闭扩展器。
无论我使用的是调试版本还是发布版本,以及我是在 IDE 中运行还是从桌面运行,都会出现延迟。
我尝试针对不同版本的 .NET 框架进行构建,但无济于事。
我推测这里发生的事情是渲染线程中的某种死锁。我的意思是,我想不出任何方式,一个以 2GHz 运行指令的 CPU 可能会花费 30 秒来弄清楚如何在屏幕上排列 30 个矩形。但我看不出有什么办法可以控制它。
如何诊断此问题的原因?当然,修复它?正如您可能想象的那样,如果我无法修复它,这将是一个扼杀项目的错误。
编辑:
我应该补充一点,我尝试过但无济于事的一件事是禁用硬件加速,如here 所述。这没有可察觉的效果。我也尝试使用参考光栅器,只是它太慢了,我什至无法让我的应用程序开始挂起。
【问题讨论】:
-
你有没有弄明白这件事?在几乎所有方面,我都遇到了与 Silverlight 非常相似的问题。唯一的区别是挂起不会持续发生。
标签: wpf performance rendering