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?
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:)
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ń."
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:
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