Binding to list causes memory leak

前端 未结 2 444
没有蜡笔的小新
没有蜡笔的小新 2020-12-16 04:58

When I bind an ItemsSource of a ListBox to a List the binding engine holds on to the list elements after the control is gone. This causes all the list elements to stay in me

2条回答
  •  温柔的废话
    2020-12-16 05:55

    I had a look at your example with JustTrace memory profiler and apart from an obvious question why would you kill view model / nullify DataContext and leave view running (in 99.9% of cases you'd kill View and DataContext - hence ViewModel and Bindings go of of scope automatically) here's what I found.

    It will work fine if you modify your example to:

    • replace DataContext with new instance of view model, as expected, existing instances of Person go out of scope as MS.Internal.Data.DataBingingEngine flushes all bindings, even they were strong refs not managed by WeakPropertyChangedEventManager , or:
    • ViewModel to replace List with new instance of IEnumerable i.e. new Person[0]/simply null and raise INCP.PropertyChanged("List") on the ViewModel

    Above modifications prove you can safely use IEnumerable/IEnumerable in binding. BTW, Person class doesn't need to implement INPC neither - TypeDescriptor binding/Mode=OneTime don't make any difference in this case, I verified that too. BTW, bindings to IEnumerable/IEnumerable/IList are wrapped into EnumerableCollectionView internal class. Unfortunatelly, I didn;t have a chance to go through MS.Internal/System.ComponentModel code to find out why ObservableCollection works when setting DataContext = null, probably because Microsoft guys did a special handing when unsubscribing from CollectionChanged. Feel free to waste few precious lifetime hours on going through MS.Internal/ComponentModel :) Hope It helps

提交回复
热议问题