7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Behavior と DependencyPropertyDescriptor の危険な関係

Last updated at Posted at 2014-08-30

参考:
http://www.programmingtidbits.com/post/2013/03/13/Blend-Behaviors-And-DependencyPropertyDescriptor-Equals-Memory-Leak.aspx
http://agsmith.wordpress.com/2008/04/07/propertydescriptor-addvaluechanged-alternative/

以下のように Behavior.OnAttached の中で DependencyPropertyDescriptor.AddValueChanged
を実行するとメモリリークします。

public class HogeBehavior : Behavior<FrameworkElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        DependencyPropertyDescriptor
            .FromProperty(FrameworkElement.ActualHeightProperty, typeof(FrameworkElement))
            .AddValueChanged(AssociatedObject, ActualHeightChanged);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        DependencyPropertyDescriptor
            .FromProperty(FrameworkElement.ActualHeightProperty, typeof(FrameworkElement))
            .RemoveValueChanged(AssociatedObject, ActualHeightChanged);
    }

    private void ActualHeightChanged(object sender, EventArgs e)
    {

    }
}

OnDetaching で解除できるように見えますが、AddValueChanged で AssociatedObject が参照され続けてしまうため、永久に解除されません。
参照を解除しないと OnDetaching が実行できない → OnDetaching を実行しないと参照を解除できない、というデッドロックに陥っているためです。

参考にしたページでは、解決方として DepenencyObject と Biniding を使った方法を紹介しています。
Binding であれば WeakReference なので問題なさそうですね。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?