2010-05-21 2 views
1

У меня есть окно WPF, которое открывает модальное дочернее окно для загрузки некоторых данных. Оба окна имеют собственную viewmodel, теперь у меня есть эта проблема: после закрытия дочернего окна она все еще работает в фоновом режиме!WPF родительско-дочернее окно: ссылка ссылочная проблема

Чтобы закрыть дочернее окно, я устанавливаю DialogResult из команды viewmodel; теперь, если я создаю новые данные, а затем редактирую их из родительского окна (с закрытым дочерним окном раньше), дочернее окно по-прежнему захватывает событие с измененным свойством для свойств, которые ранее связывались.

Как это можно избежать?

Я бы очистил каждую ссылку данными при закрытии модального окна. Какая из них лучшая практика?

ответ

3

Убедитесь, что вы не держите ссылки на свое окно, даже косвенное. Одной из наиболее распространенных причин утечек являются события. Если окно B добавляет обработчик события к событию окна A, B не будет выпущен до тех пор, пока не появится A.

Например, если вы непосредственно слушаете изменения свойств, вы должны использовать Weak Event Pattern и заменить все ваши + = на вызов PropertyChangedEventManager .AddListener. В общем, каждый сильный обработчик, добавляемый к событию, должен быть удален, чтобы избежать утечки.

Дополнительная информация о утечках в .NET в this MSDN article.

Вы можете использовать профилировщик памяти, например, профилировщик памяти Scitech или Jetbrains dotTrace, чтобы узнать, какие объекты хранят ваши окна в памяти.


Edit: В ответ на ваши комментарии, ваш случай действительно проще, чем я думал: сборщик мусора просто не собрать окно еще. Добавление GC.Collect на Test_Click для целей тестирования решает проблему.

Здесь удалите событие SelectionChanged из ComboBox, когда форма закрывается, поэтому вы можете позволить GC выполнить свою работу и вернуть форму позже, не имея проблем. Если вам действительно нужна вся форма для освобождения прямо сейчас, вы можете подумать о вызове GC.Collect, хотя вам следует избегать его, когда сможете.

Редакция 2: В ответ на ваш третий комментарий это должно иметь значение только для объектов, которые разделяются между представлениями, и где изменения в представлении будут что-то менять в общем объекте. В вашем тестовом проекте SelectionChanged ничего не делает в исходном списке, поэтому на самом деле не имеет значения, было ли событие поднято или нет. Форма будет собрана в конечном итоге.

+0

Я проверяю ... моя сущность реализует интерфейс INotifyPropertyChanged, свойство объекта связывается с SelectedValue из ComboBox в дочернем выигрыше; ComboBox, в коде дочернего окна позади, имеет обработчик событий для SelectionChanged. Затем, после того, как я закрыл дочернее окно, если я изменяю одно и то же свойство сущности в родительском окне, запускается обработчик обработчика Selectionboanged из ComboBox в дочернем окне. –

+0

Я создал глупый проект, демонстрирующий поведение. Вы можете скачать его с thi url: http://www.olisoft-olisistemi.it/uploads/WpfApplication2.zip 1) Нажмите кнопку «ChildWindow» 2) Закрыть ChildWindow 3) Нажмите кнопку «Тест» -> событие SelectionChanged для ComboBox в режиме ChildWindow! Неправильно?Слабый шаблон событий - это решение? –

+0

Спасибо, но если у моего окна больше событий по коду, каждый раз я должен удалить все события закрытия консоли обработчика? Или существует лучший подход? –

Смежные вопросы