Почему пользовательский контроль WPF с привязкой не получает сборщик мусора? - PullRequest
4 голосов
/ 19 августа 2010

Наше приложение добавляет и удаляет пользовательские элементы управления WPF (4.0) из своего главного окна, и мы заметили, что они не собирают мусор (через 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 User Control (Кодовый код является стандартным и не был изменен

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

objAlive - false, но ctlAlive - true. Если привязка удаляется из XAML UserControl, оба имеют значение false. Если я подключу профилировщик памяти, MyCtl все еще висит, но я не могу понять, что на него ссылается (советы по его поиску с помощью jetBrains приветствуются).

Это ожидаемое поведение или мне нужно сделать больше для очистки моих пользовательских контроллеров WPF?

1 Ответ

4 голосов
/ 03 февраля 2011

Зависит от того, к чему вы привязываетесь.

Это может быть известной проблемой: http://support.microsoft.com/kb/938416

Привязываете ли вы к пользовательскому классу?Вы внедрили INotifyPropertyChanged или создали DependencyProperty?

...