我正在构建一个 WPF 应用程序,该应用程序使用 LINQ to SQL 连接到 SQL Server 数据库。
应用程序的主窗口包含ListView
一系列详细视图。的绑定到作为根视图模型上的属性公开的详细视图模型对象的集合ItemSource
。ListView
每个详细视图模型对象都包含多个ICommand
属性以及一个公开详细模型对象的属性,该详细模型对象又公开了 UI 中显示的各种数据字段。
使用 ANTS 内存分析器的分析表明,被泄漏的对象是包含在详细模型对象中的对象,以及它们所绑定的一些 UI 类。以前刷新的这些对象的实例不会被垃圾收集。
ANTS 有一个工具,允许用户跟踪引用链,以确定保留不需要的内存的原因。当我使用它时,我发现所有出现的链条都有一个ICommand
。因此,我删除了有问题的ICommand
,发现内存泄漏消失了。
不幸的是,我需要ICommand
实现一些重要的功能。真正让我困惑的是它首先是如何引用细节模型对象的——它们是细节视图模型对象中两个完全独立的实例变量。
这是详细视图模型对象的构造函数(对RootViewModel的引用用于在连接到ICommands的某些方法中进行回调。我最初怀疑这可能导致引用循环链,这可能是导致问题,但删除它似乎没有任何效果。)
public CarDataViewModel(CarData carDataItem, RootViewModel parentViewModel)
{
_parentViewModel = parentViewModel;
CarDataModel = carDataItem;
CompetingCheckboxStatus = CarDataModel.CurrentCar.Competing;
AcknowledgeAlarm = new ParameterlessCommand(AcknowledgeAlarmClicked);
Acknowledge = new ParameterlessCommand(AcknowledgeClicked);
ShowReport = new ParameterlessCommand(ShowReportClicked);
Cancel = new ParameterlessCommand(CancelClicked);
}
这是设置绑定的 xaml - AcknowledgeAlarm 是 ICommand,CarDataModel 是详细模型对象:
<ListView x:Name="itemGridView"Grid.Row="1"ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding CarDataViewModels}" IsSynchronizedWithCurrentItem="True" Margin="0,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
</DataTemplate.Resources>
<Button Command="{Binding AcknowledgeAlarm}">
<Border DataContext="{Binding CarDataModel}" BorderBrush="{StaticResource GrayFadeBrush}" Background="White" BorderThickness="5">
<Grid> . . .