【发布时间】:2014-10-10 17:31:46
【问题描述】:
我正在开发一个 WPF 应用程序,其中我正在使用 CustomObject 的 ObservableCollection
public ObservableCollection<ProjectsToShow> Projects{get;set;}
ProjectsToShow 类的定义
public class ProjectsToShow
{
public ProjectsToShow()
{
Wells = new ObservableCollection<WellsToShow>();
}
public Project ProjectObject { get; set; }
ObservableCollection<WellsToShow> _wells;
public ObservableCollection<WellsToShow> Wells{get;set;}
}
该类为 WellsToShow 初始化一个集合,其定义为
public class WellsToShow
{
public WellsToShow()
{
Datasets = new ObservableCollection<DatasetsToShow>();
}
public Well WellObject { get; set; }
ObservableCollection<DatasetsToShow> _datasets;
public ObservableCollection<DatasetsToShow> Datasets
{
get { return _datasets; }
set
{
_datasets = value;
NotifyPropertyChanged("Datasets");
}
}
}
还有一个像这样的级别。
现在我正在使用内存分析器分析我的应用程序,它会不断将集合中的对象添加到内存中。我期待着那个电话
Projects.Clear();
将从内存中释放所有对象,但它不会那样工作。即使我尝试将项目设置为空,但即使这样也没有用。 WellsToShow 和 DatasetToShow 的对象仍然保留在内存中。因此,出于测试目的,我尝试使用此代码
foreach(var project in MainViewModel.Projects)
{
foreach(var well in project.Wells)
{
well.Datasets.Clear();
}
project.Wells.Clear();
}
MainViewModel.Projects.Clear();
根据内存分析器,它们不再在内存中。作为记录,每次我运行分析器时,它都会先运行 GC.Collect,然后再进行分析。
请解释一下这个东西是如何工作的。如果这是清除集合的正确方法,那么我需要在所有项目中运行并修复这个东西。
更新1,将此集合绑定到视图
我正在将我的 Project 属性绑定到 TreeView 控件,并在对其进行探查时进行调查。此控件保留了我的收藏,我认为清除项目源收藏应该可以完成这项工作,但这里不是这种情况。
<TreeView VirtualizingStackPanel.IsVirtualizing="False" ItemsSource="{Binding Projects}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type bll:ProjectsToShow}" ItemsSource="{Binding Wells}">
<TextBlock HorizontalAlignment="Stretch" Text="{Binding ProjectName}" x:Name="TextBlockProject" Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}">
<TextBlock.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" >
<MenuItem
Command="{Binding FileEditProjectCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource EditProject}"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Command="{Binding FileDeleteProjectCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource DeleteProject}"/>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type bll:WellsToShow}" ItemsSource="{Binding Datasets}">
<TextBlock HorizontalAlignment="Stretch" Text="{Binding WellName}" Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}">
<TextBlock.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Command="{Binding FileEditWellCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource EditWell}"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Command="{Binding FileDeleteWellCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource DeleteWell}"></TextBlock>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
附上更新 2 截图
【问题讨论】:
-
如果您正在使用分析器,请检查哪些对象导致了井和数据集被扎根。它可能是一个绑定到您的视图模型的视图,使它们保持活动状态。
-
您能在 View 中显示绑定吗?
-
@mikez 我已经更新了这个问题。请立即调查。
-
@MegaMind - Profiler 还会告诉您根对象的详细信息。查看哪些对象保留了您的引用。
-
@RohitVats MainWindow->TreeView->System.Windows.DataBinding->DatasetsToShow
标签: c# wpf garbage-collection observablecollection