Страницы

Поиск по вопросам

четверг, 23 января 2020 г.

Простой WPF Binding. Будет ли утечка памяти?

#wpf #xaml


Уважаемые гуру, прошу растолковать по привязкам. В учебных статьях "для чайников"
вопросы утечек вообще не рассматриваются, а самостоятельный поиск информации по частям
привел к тому, что я запутался. Что я нарыл:
Для борьбы с утечками памяти в WPF, нужно привязываться к объектам, реализующим INotifyCollectionChanged.
Ок, в случае коллекций, все понятно. Привязываемся через ObservableCollection.
Но как быть с простыми типами данных?
Допустим у нас простая страничка, на которой есть текстовое поле, куда пользователь
вводит свое имя. Для работы с этим именем, привяжем его к полю name.

View:





ViewModel:

public string name {get; set;}
...
this.DataContext = this;
this.InitializeComponent();


Согласно этой страницы, для борьбы с утечкой, необходимо или реализовать INotifyPropertyChanged
на объекте-источнике, либо сделать свойство DependencyProperty. Но я нигде не могу
найти простой пример, как это правильно сделать.



Тут, в последнем абзаце, вообще написано:


  Если вы используете .NET Framework 4.5, то у вас не будет утечки
  памяти


Так как правильно реализовать привязку данных?
    


Ответы

Ответ 1



В документе, на которые вы ссылаетесь, написано следующее: This issue occurs if the following conditions are true: A data-binding path refers to property P of object X. Object X contains a direct reference or an indirect reference to the target of the data-binding operation. Property P is accessed through a PropertyDescriptor object instead of a DependencyProperty object or a PropertyInfo object. Из этих условий необычным является второе: «Object X contains a direct reference or an indirect reference to the target of the data-binding operation». Если вы программируете с использованием MVVM, ваш объект X скорее всего VM-объект, а целевой элемент привязки — View-объект. В нормальной ситуации объекты VM не имеют права знать о View, и таким образом не должны содержать на него прямых или непрямых ссылок. Значит, проблема может возникнуть только если у вас View-объект ссылается на другой View-объект. Но свойства UI-объектов обычно являются DependencyProperty, поэтому этот случай тоже в подавляющем большинстве случаев не имеет места. Что нужно делать? Если вы производите Binding UI-объекта к другому свойству UI-объекта, имеет смысл обратить внимание на то, является ли то, что вы привязываете, DependencyProperty. В подавляющем большинстве случаев это так и будет. Если всё же оказывается, что вам кровь из носу нужно забиндить свойство одного UI-объекта на другое свойство, которое не является DependencyProperty (например, как в примере из статьи, которую вы привели: в этом примере memory leak возникает и в VS 2015), вам нужно поменять Binding на OneTime: в этом случае всё равно вы не получаете нотификаций об изменении свойства (т. к. INotifyPropertyChanged не реализовано, и свойство не есть DependencyProperty). Более прагматичный подход — не парьтесь с каждой привязкой, тестируйте ваше приложение при помощи memory profiler'а, и если обнаружите утечку памяти, описанную в статье, почините её как указано в п. 2.

Комментариев нет:

Отправить комментарий