Czy wiązania mogą powodować wycieki pamięci w WPF?

Czy muszę odłączać elementy, gdy element znika, aby zapobiec wyciekom pamięci? Myślę, że trochę się martwię, że jeśli przeładuję i Nowy szablon zostanie zastosowany do kontrolki, a w tym szablonie istnieje powiązanie z zewnętrznym elementem, czy mogłoby to zapobiec zbieraniu kontroli wykonanej dla szablonu?

Author: Anatoliy Nikolaev, 2013-08-31

3 answers

Jeśli nie jesteś związany z DependencyProperty lub obiektem, który implementuje INotifyPropertyChanged, wtedy powiązanie może wyciekać pamięć i będziesz musiał się rozłączyć, gdy skończysz.

Dzieje się tak dlatego, że jeśli obiekt nie jest DependencyProperty lub nie implementuje INotifyPropertyChanged, to wykorzystuje Zdarzenie ValueChanged Poprzez PropertyDescriptors AddValueChanged metoda. To powoduje, że CLR tworzy silne odniesienie z PropertyDescriptor do object i w większości przypadków CLR będzie przechowywać odniesienie do PropertyDescriptor w globalnej tabeli.

Ponieważ Wiązanie musi Kontynuuj słuchanie zmian. To zachowanie utrzymuje odniesienie żywe między PropertyDescriptor i object, gdy cel pozostaje w użyciu. Może to spowodować wyciek pamięci w object i dowolnych object, do których odnosi się object, obejmuje to cel wiązania danych.

Więc w skrócie, jeśli jesteś związany z DependencyProperty LUB INotifyPropertyChanged obiektem, powinno być ok, w przeciwnym razie, jak każde subskrybowane wydarzenie, powinieneś zrezygnować z subskrypcji wiązań


Edit: Istnieje możliwość, że zostało to naprawione w .NET4.5 używając słabych zdarzeń/odniesień, ale po kilku szybkich testach wydawało mi się to samo, będę musiał zanurkować głębiej, aby potwierdzić, więc osobiście powiem w Może być naprawione w 4.5:)

 59
Author: sa_ddam213,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-08 01:47:46

Z http://msdn.microsoft.com/en-us/library/aa970850.aspx , WPF używa słabych wzorców zdarzeń, które nie zawierają silnych odniesień do obiektów i pozwalają im być GC ' ED, jeśli są jedynymi odniesieniami do obiektu.

" wiele aspektów powiązania danych WPF ma już słaby wzorzec zdarzeń zastosowany w sposobie implementacji zdarzeń."

 6
Author: jdphenix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-30 23:47:46

Nie udawaj, że odpowiadasz, tylko w celach informacyjnych. W klasycznym artykule na temat Finding Memory Leaks in WPF-based applications autor Jossef Goldberg , szczegółowo opisał przypadki, w których może wystąpić wyciek pamięci w aplikacji WPF. Tak naprawdę większość odnosi się do.NET 3.5/4.0, ale niektóre przypadki mogą być istotne do dziś. Również mieć małe rozszerzenie .

Cytat o wycieku w Binding:

Cause:

Ten wyciek udokumentowany w tym Kb Artykuł. Jest wyzwalany ponieważ:

Kontrola TextBlock ma powiązanie z obiektem (myGrid), który ma odniesienie do TextBlock (jest jednym z dzieci myGrid).

Note: ten rodzaj wycieku danych jest unikalny dla konkretnego scenariusza (a nie dla wszystkich scenariuszy tworzenia danych), jak udokumentowano w artykule kb. Właściwość Path jest nie DependencyProperty i nie na klasie, która implementuje INotifyPropertyChanged, a ponadto łańcuch silnych wartości musi istnieć.

Kod:

myDataBinding = new Binding("Children.Count");
myDataBinding.Source = myGrid; 
myDataBinding.Mode = BindingMode.OneWay;
MyTextBlock.SetBinding(TextBlock.TextProperty, myDataBinding);

Ten sam nieszczelny kod można również zapisać w XAML:

<TextBlock Name="MyTextBlock" 
           Text="{Binding ElementName=myGrid, Path=Children.Count}" />

Fix/Workaround:

Istnieje kilka podejść, najłatwiejszym jest po prostu wyczyszczenie wiązania, gdy okna mają się zamknąć.

Np.:

BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);

Innym sposobem jest ustawienie trybu powiązania danych na OneTime. Zobacz Kb Artykuł dla innych pomysłów.

Przydatny link:

Unikanie wycieku pamięci WPF z DataBinding

 6
Author: Anatoliy Nikolaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-31 12:02:58