Утечка памяти хоста элемента WPF - PullRequest
7 голосов
/ 16 июня 2011

У меня странная утечка памяти при использовании элемента host на окнах форм. У меня есть основная форма, которая открывает другую форму, та, которая имеет только элемент elementhost (который на данный момент не имеет дочернего элемента управления wpf). Только 1 хост-форма может быть открыта. Каждый раз, когда я открываю форму, память приложения увеличивается на 20 МБ, что не является свободным при закрытии формы, поэтому после нескольких раз открытия формы хоста у меня заканчивается память !. Теперь, если я удаляю элемент host из формы, память остается стабильной.

Я использовал CLRProfiler и ANTS, но обнаружил, что все проблемы находятся на хосте элемента, и я не нашел обходного пути для этого.

wpfHost используется "из коробки", просто перетаскивается с панели инструментов в winForm.

Есть идеи, как мне это решить?

Ответы [ 3 ]

8 голосов
/ 28 ноября 2014

если ссылка снова разорвется, вот решение (скопировано)

Автор: КГр 22.10.2010 в 6:12 Возможный обходной путь: Поместите следующий код вDispose или другой метод выпуска вашего элемента управления / формы, который содержит элемент управления ElementHost.

if (elementHost != null)
{
    FrameworkElement fe = elementHost.Child as FrameworkElement;
    if (fe != null)
    {
        // Memory leak workaround: elementHost.Child.SizeChanged -= elementHost.childFrameworkElement_SizeChanged;
        SizeChangedEventHandler handler = (SizeChangedEventHandler)Delegate.CreateDelegate(typeof(SizeChangedEventHandler), elementHost, "childFrameworkElement_SizeChanged");
        fe.SizeChanged -= handler;
    }
    elementHost.Child = null;
    base.Dispose(disposing);
    elementHost.Dispose();
    elementHost.Parent = null;
    elementHost = null;
}
2 голосов
/ 16 июня 2011

Основной причиной «утечек памяти» в приложениях .NET являются обработчики событий. Если объект A обрабатывает событие, вызванное объектом B, объект A может выйти из области видимости, и он не будет уничтожен, потому что даже если ваш код не сохраняет ссылку на него, объект B делает.

В WinForms некоторые объекты пользовательского интерфейса (ToolStripButton - хороший пример) регистрируются в Windows для обработки событий смены темы. Windows хранит ссылку на них, чтобы они могли сказать им, если пользователь меняет тему. Досадно, что эти объекты не отменяются, если форма, на которой они находятся, закрывается, в результате чего их форма уничтожается, но они этого не делают.

Итак, как, черт возьми вы уничтожаете один из этих объектов? В случае ToolStripButton установка Visible на false делает свое дело. Оказывается, переключение Visible также переключает, обрабатывает ли элемент управления события смены темы. Поэтому, если вы установите Visible на false, элемент управления будет отменен, а затем, когда он выйдет за пределы области видимости, он действительно может быть уничтожен.

Возможно, это поможет с ElementHost, по той же или по аналогичной причине. Трудно сказать, потому что, как вы обнаружите, если вы изучите эту проблему, она не совсем, вы знаете, задокументирована.

0 голосов
/ 06 октября 2011

У меня есть объект WPF ElementHost в моей форме, и я также заметил утечку памяти.То, что я делал, было что-то вроде этого:

VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject;

и он делал бы это в области видимости IE:

Private void Myfunction()
{

   VAR cnt=this.MyHostControl.Child as MyWPFControl.WPObject;
   cnt.Myproerty="Issue";

}

Не был большим поклонником VAR (напоминает старый COMдней), я решил создать глобальный объект, подобный этому:

MyWPFControl.WPObject cnt = null;

Затем на FormLoad_EvenT()

я инициализировал объект cnt примерно так:

cnt = this.MyHostControl.Child as MyWPFControl.WPObject;

Теперь моя ссылка выглядит следующим образом:

Private void Myfunction()
{

   cnt=this.MyHostControl.Child as MyWPFControl.WPObject;
   cnt.Myproerty="Issue";

}

И мне не нужно создавать var объект.

Все еще тестирую, и похоже, что это, возможно, работает.Со временем увидим.

...