我这样定义了我的绑定(bind):
<TreeView
ItemsSource="{Binding UsersView.View}"
ItemTemplate="{StaticResource MyDataTemplate}"
/>
CollectionViewSource 是这样定义的:
private ObservableCollection<UserData> users;
public CollectionViewSource UsersView{get;set;}
UsersView=new CollectionViewSource{Source=users};
UsersView.SortDescriptions.Add(
new SortDescription("IsLoggedOn",ListSortDirection.Descending);
UsersView.SortDescriptions.Add(
new SortDescription("Username",ListSortDirection.Ascending);
到目前为止一切顺利,按预期工作: View 首先显示按字母顺序登录的用户,然后显示未登录的用户。
但是,UserData 的 IsLoggedIn 属性每隔几秒由后台工作线程更新一次,然后代码调用:
UsersView.View.Refresh();
在 UI 线程上。
这再次按预期工作:登录的用户从 View 底部移动到顶部,反之亦然。但是:每次我在 View 上调用 Refresh 方法时,应用程序都会囤积 3.5MB 的额外内存,这些内存只会在应用程序关闭后(或在 OutOfMemoryException 之后...)释放
< p>我做了一些研究,下面是无效修复的列表:
- UserData 类实现 INotifyPropertyChanged
- 更改基础用户集合根本没有任何区别:任何 IENumerable
<UserData
> 作为 CollectionViewSource 的源会导致问题。
- 将 ColletionViewSource 更改为列表<UserData
>(并刷新绑定(bind))或从 ObservableCollection 继承以获取对底层 Items 集合的访问权限以对其进行排序是行不通的。
我没脑子了!帮忙?
编辑: 我找到了: Resource MyDataTemplate 包含一个绑定(bind)到 UserData 对象以显示其属性之一的 Label,UserData 对象由 TreeView 的 ItemsSource 传递下来。 Label 有一个这样定义的 ContextMenu:
<ContextMenu Background="Transparent" Width="325" Opacity=".8" HasDropShadow="True">
<PrivateMessengerUI:MyUserData IsReadOnly="True" >
<PrivateMessengerUI:MyUserData.DataContext>
<Binding Path="."/>
</PrivateMessengerUI:MyUserData.DataContext>
</PrivateMessengerUI:MyUserData>
</ContextMenu>
MyUserData 对象是一个 UserControl,显示 UserData 对象的所有属性。通过这种方式,用户首先只能看到用户的一条数据,然后通过右键单击可以看到所有数据。
当我从 DataTemplate 中删除 MyUserData UserControl 时,内存泄漏就消失了!我怎样才能仍然实现上面指定的行为?
最佳答案
排除内存泄漏的第一步是找到明确的来源。这并不总是很明显,有时会违背您的直觉。根据您的解释,如果删除用户控件,问题就会消失,但是当您将其放回去时,又会开始泄漏。这很可能指向该控件内的内存泄漏(尽管不一定)。也许您的控件适合 one of the many types of WPF memory leaks ,或者您有一个更经典的问题,即订阅事件但在不再需要时没有正确取消绑定(bind)(the weak event pattern 在这里很有用)。
最好的办法是使用像 .NET Memory Profiler 这样的工具或 ANTS Memory Profiler (两者都非常好并且有免费试用)。使用这些工具中的一种,找到应该消失后仍四处游荡的对象。这些工具有助于跟踪卡在您的对象上的对象链。 their sites 上有很多关于内存分析的好文章,在 SO 和广泛开放的网络上。
关于c# - CollectionView.View.Refresh 上的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2431985/