Автоматически звонящий OnDetaching () для Поведений Silverlight

Я использую несколько поведений Смешения и включаю управление Silverlight. Я задаюсь вопросом, существует ли какой-либо механизм для того, чтобы автоматически отсоединить или гарантировать, что OnDetaching () называют для поведения или триггера, когда управление больше не используется (т.е. удаляется из визуального дерева).

Моя проблема состоит в том, что существует утечка управляемой памяти с управлением из-за одного из поведений. Поведение подписывает на событие на некотором долговечном объекте в OnAttached () переопределение и должно отказываться от подписки от того события в OnDetaching () переопределение так, чтобы это могло стать кандидатом на сборку "мусора". Однако OnDetaching () никогда, кажется, не становится названным, когда я удаляю управление из визуального дерева... единственный способ, которым я могу добраться, это для случая путем явного отсоединения проблематичных поведений ПРЕЖДЕ, ЧЕМ удалить управление, и затем это правильно собрано "мусор".

Прямо сейчас мое единственное решение состояло в том, чтобы создать открытый метод в коде - позади для управления, которое может пройти и отсоединить любые известные поведения, которые вызвали бы проблемы сборки "мусора". Это было бы до клиентского кода для знания для вызова этого прежде, чем удалить управление из панели. Мне действительно не нравится этот подход, таким образом, я ищу некоторый автоматический способ сделать это, что я пропускаю или лучшее предложение.

public void DetachBehaviors()
{
     foreach (var behavior in Interaction.GetBehaviors(this.LayoutRoot))
     {
          behavior.Detach();
     }

     //continue detaching all known problematic behaviors on the control....
}
5
задан Dan Auclair 22 April 2010 в 16:41
поделиться

1 ответ

Что вам действительно нужно в этом случае, так это не какой-то способ автоматического отключения, а обеспечение того, чтобы ссылка, удерживаемая долгоживущим объектом, не сохраняла поведение ( и, следовательно, все остальное, на что он ссылается), не подлежит сборке мусора.

Это достигается путем реализации паттерна «Посредник». Идея состоит в том, что вы не передаете объекту-долгоживущему делегат со ссылкой на ваше Behavior , вместо этого вы создаете класс Mediator в качестве посредника. Посредник присоединяется к событию долгоживущих объектов и содержит WeakReference поведения. Когда долгоживущий объект запускает событие, посредник проверяет, что WeakReference все еще жив, и в таком случае вызывает на нем метод для передачи события.Если при возникновении события посредник обнаруживает, что WeakReference больше не работает, он отключает свой обработчик событий от долгоживущего объекта.

Следовательно, ничто не препятствует этому поведению, и все остальное, что связано с сборкой мусора, остается лишь очень маленьким экземпляром посредника с мертвой ссылкой, все еще прикрепленной к долгоживущему объекту. Поскольку эти посредники крошечные, они не представляют реальной проблемы, и даже они исчезнут при следующем запуске события.

К счастью, вам не нужно создавать это самостоятельно, другие уже сделали это. Он называется WeakEventListener . Этот блог: Выделение «слабого» вклада; Улучшения делают предотвращение утечек памяти с помощью WeakEventListener еще проще! содержит отличный набор ссылок по этой теме.

3
ответ дан 14 December 2019 в 13:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: