一个带有绑定的WPF UserControl为什么无法被垃圾回收?

5
我们的应用程序在其主窗口中添加和移除WPF(4.0)UserControl,并且我们注意到它们没有被垃圾回收(通过永远不返回null的WeakReferences)。即使控件从未添加到树中,如果一个UserControl有绑定,这种情况似乎也会发生。以下是在控制台应用程序中最简单的复现方式:

主程序

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        var obj = GetObj();
        var ctl = GetCtl();
        for (int x = 0; x < 4; x++)
        {
            GC.Collect();
            Thread.Sleep(1000);
        }
        bool objAlive = obj.IsAlive;
        bool ctlAlive = ctl.IsAlive;
        Console.WriteLine(objAlive + "-" + ctlAlive);
        Console.ReadLine();
    }

    private static WeakReference GetObj()
    {
        return new WeakReference(new object());
    }

    private static WeakReference GetCtl()
    {
        return new WeakReference(new MyCtl());
    }
}

MyCtl用户控件(代码后台是标准的,未被修改)

<UserControl <!--Snip Default Namespaces-->>
    <TextBlock Text="{Binding Blah}" />
</UserControl>

objAlive为false,但ctlAlive为true。如果从UserControl XAML中删除绑定,则两者都为false。如果我连接一个内存分析器,MyCtl仍然存在,但是我无法弄清楚是什么在引用它(使用jetBrains的提示将有所帮助)。

这是否是预期行为,还是我需要更多地清理我的WPF UserControls?

1个回答

4

取决于你绑定的是什么。

这可能是一个已知问题:http://support.microsoft.com/kb/938416

你是否绑定到自定义类?你是否实现了INotifyPropertyChanged或创建了DependencyProperty?


这似乎很可能,我们已经实现了INotifyPropertyChanged。 - Robert Wagner
看起来上面的链接已经失效了,有人知道我可以在哪里找到这个吗? - ymbcKxSw
简而言之,您需要使用INotifyPropertyChanged或DependencyProperty,否则由于框架使用PropertyDescriptors进行绑定,可能会导致内存泄漏。 PropertyDescriptors创建的强对象引用可能会阻止垃圾回收器销毁对象。 - bigtlb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接