A memory leak may occur when you use data binding in Windows Presentation Foundation


When you use data binding in Microsoft Windows Presentation Foundation (WPF), a memory leak may occur.


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.


To work around this issue, use one of the following methods.

Method 1

Access property P through a DependencyProperty object.

Method 2

Expose the INotifyPropertyChanged interface on object X.

Method 3

Set the mode of the data binding to OneTime.


This behavior is by design.

More Information

In WPF, a data-binding operation that is not marked as OneTime must listen for property change notifications from the source object (object X). WPF uses the built-in notifications of the DependencyProperties class or the notifications from the INotifyPropertyChanged interface.

If the DependencyProperties class and the INotifyPropertyChanged interface are unavailable, WPF uses the ValueChanged event. This behavior involves calling the PropertyDescriptor.AddValueChanged method on the PropertyDescriptor object that corresponds to property P. Unfortunately, this action causes the common language runtime (CLR) to create a strong reference from this PropertyDescriptor object to object X. The CLR also keeps a reference to the PropertyDescriptor object in a global table. This behavior causes a reference chain to occur in the following order:
  1. Global table
  2. The PropertyDescriptor object
  3. Object X
  4. The data-binding target

    Note The reference between object X and the data-binding target is caused by the first condition that is listed in the "Cause" section.
  5. Binding

As long as the data-binding target is used, the binding must continue to listen for changes. This behavior keeps the reference alive between the PropertyDescriptor object and object X, and the target remains in use. This behavior causes a memory leak in object X and in every object to which object X refers. These objects include the data-binding target.

Workaround method 1 and workaround method 2 cause WPF to use one of the preferred notification mechanisms. Workaround method 3 instructs WPF not to listen for change notifications. All three workaround methods avoid creating the reference between the PropertyDescriptor object and object X.

In the following code example, the conditions for the leak are created.
<Label Name="MyLabel">
<Stack Panel Name="MyStackPanel">
<TextBlock Text="{Binding ElementName=MyStackPanel, Path=Children.Count}" />
In this code example, the Count property represents the property P. Additionally, object X is represented by UIElementCollection class in the form of the StackPanel.Children property.

The first condition in the "Cause" section is met because object X refers to the children of object X. These children include the binding target, and the binding target is the TextBlock element.

The second condition in the "Cause" section is met because property P is not a DependencyProperty object, and object X does not implement the INotifyPropertyChanged interface. This behavior causes the UIElementCollection class and the TextBlock element not to be released. Additionally, the StackPanel container class is not released, because the UIElementCollection class contains a reference to the StackPanel container class. This behavior occurs even if the UIElementCollection class and the TextBlock element are removed from the main tree by using the following line of code:
MyLabel.Content = <Some New Content>;


Makale No: 938416 - Son İnceleme: 23 Mar 2009 - Düzeltme: 1

Geri bildirim