In doing some memory leak testing in our app, I think we've run into a problem caused by the TreeListView. We're seeing old rows getting leaked/remembered by the grid after we raise a NotifyCollectionChangedAction.Reset event. I'd expect all references to the old rows to go away after the reset, but we were seeing them being held on.
I tried debugging it a bit and found out that the memory leak seemed to be coming from a property called ChildViewByItem in HierarchicalCollectionView. After looking further, I noticed that that property gets cleaned up via the ProcessCollectionChanged method that looks like this:
As you can see, this logic only removes 'Children View' items on Remove and Replace actions - but not on Reset. Once I saw that, I tried raising individual Remove events and the old rows were not leaked anymore! In our app, however, we are often replacing the entire contents of the collection so it doesn't make sense for us to raise a ton of individual Remove events - instead, it makes much more sense for us to raise a single Reset event.
Shouldn't that method also be doing logic on a Reset event to clear out the ChildViewByItem?
Thanks!
I tried debugging it a bit and found out that the memory leak seemed to be coming from a property called ChildViewByItem in HierarchicalCollectionView. After looking further, I noticed that that property gets cleaned up via the ProcessCollectionChanged method that looks like this:
internal
override
void
ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
{
if
((args.Action == NotifyCollectionChangedAction.Remove) || (args.Action == NotifyCollectionChangedAction.Replace))
{
int
count = args.OldItems.Count;
for
(
int
i = 0; i < count; i++)
{
object
item = args.OldItems[i];
this
.CollapseOnSourceRemove(item);
this
.RemoveChildrenView(item);
}
}
base
.ProcessCollectionChanged(args);
}
As you can see, this logic only removes 'Children View' items on Remove and Replace actions - but not on Reset. Once I saw that, I tried raising individual Remove events and the old rows were not leaked anymore! In our app, however, we are often replacing the entire contents of the collection so it doesn't make sense for us to raise a ton of individual Remove events - instead, it makes much more sense for us to raise a single Reset event.
Shouldn't that method also be doing logic on a Reset event to clear out the ChildViewByItem?
Thanks!