Memoryleak DependencyProperty



  • Hallo Leute,

    Nehmen wir an, ich habe ein Control und darin ein DP! In dessen PropertyChangedCallback hänge ich mich an ein EventHandler des Dependency Object (Function)!

    bsp:

    public Function MyFunction
    		{
    			get { return (Function)GetValue(MyFunctionProperty); }
    			set { SetValue(MyFunctionProperty, value); }
    		}
    
    		// Using a DependencyProperty as the backing store for MyFunction.  This enables animation, styling, binding, etc...
    		public static readonly DependencyProperty MyFunctionProperty =
    			DependencyProperty.Register("MyFunction",
    			typeof(Function), typeof(UserControl1), new UIPropertyMetadata(null, OnPropChange));
    
    		private static void OnPropChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    		{
    			var me = (UserControl1)d;
    			Console.WriteLine("OnPropChange");
    			((Function)e.NewValue).DataChange += me.MyFunction_DataChange;
    		}
    

    Wenn ich nun das Control lösche, wird diese nich wirklich vom GC gelöscht, da sich eben noch ein registiertes event an dem DP befindet!

    Gibt es ne möglichkeit, dass das DP mitbekommt, wenn sein Hostcontrol gelöschtw erden will, so dass ich den eventhänderl entfernen kann!

    Ich hab es mal testhalber in dem UnLoaded event des Controls gemcaht, und es hat funktioniert, allerding weiß ich nicht ob das ne saubere lösung ist!

    Ich bräuchts quasi ein OnDependencyPropertyBindingDisposed event:)

    grüße





  • Diesen Beitrag kenne ich, aber der löst das Problem nicht, da wird leider nicht beschreiben wie ich ein dispos- callback erhalten wenn sich das host-Control löscht



  • Sieh dir in dem Artikel noch mal die Methode OnFooChanged() an, besonders den Part mit

    if (!BindingOperations.IsDataBound(source, FooProperty)) {...}
    


  • Das is richtig,

    aber wenn das Control ,welches das entsprechende DP enhält "gelöscht wird" dann bekomm ich eben kein "OnFooChanged" event!?!? Das wird ja aufgerufen, wenn das Binding geändert wird, aber wenn ich das Control lösche nicht!?

    Oder steh ich jetzt aufm Schlauch?



  • Dein 1. Problem ist dass du die Phrase "Control wird gelöscht" im Kopf hast. WPF löscht aber keine Controls. Die werden einfach irgendwann vom GC aufgesammelt und sind dann halt einfach weg.

    Dein 2. Problem ist dass du immer nur connectest aber nie disconnectest.

    Davon abgesehen: Weak Event Patterns

    Wenn du allerdings gleichzeitig sicherstellen willst dass du keine Performance verschenkst, dann solltest du vielleicht dafür sorgen dass der Event immer nur connected ist während das Control "loaded" ist.
    Also in OnPropChange nur connecten/disconnecten wenn "loaded", in den load/unload Handlern connecten bzw. disconnecten wenn die Property != null ist.



  • 1. Richtig, in meiner TestAnwendung erzeuge ich ein Control, und weiße es einem ContentControl zu, danach hole ich mir das controkl wieder aus dem Contentcontrol und setze die Referenz auf null, so dass der GC weiß, dass er das control löschen kann ! das sehe ich am Destructor aufruf! in dem ich GC.Collect explizit aufrufe !

    2. Genau, eben das beschreibt mein Problem, ich WILL ja disconnecten, aber die frage ist wann ich das machen kann! Ich habe auch schon erwähnt, dass ich das im UnLoaded event des Controls das event des DP disconnectet habe, was auch klappt.. da dass controll vom GC auch gelöscht wird.. die frage war, ob das der richtige weg ist mit dem Unloaded....

    3. Weak Events wäre dann der letzte ausweg, um sicherzustellen dass ich keien memory leaks bekomme...


Log in to reply