PropertyChangedEventManager - Не приведет ли утечка к вызову RemoveHandler? - PullRequest
0 голосов
/ 03 апреля 2020

Мне интересно, будет ли приведенный ниже код вызывать утечку: Класс Parent имеет список класса Child. Child объекты используют PropertyChangedEventManager.AddHandler, чтобы получать уведомления об изменениях свойств в агрегирующем Parent объекте. Если эти агрегированные экземпляры никогда не вызовут RemoveHandler, вызовет ли это утечку?

Я понимаю, что G C основан на достижимости, а не на подсчете ссылок , но, очевидно, на PropertyChangedEventManager поддерживает список подписчиков обработчиков где-нибудь. Так как же очистить этот список, если я не позвоню RemoveHandler?

Что-то вроде этой заведомо упрощенной версии того, что делает мой код:

public class Parent : INotifyPropertyChanged
{
    public Parent()
    {
        _children = new List<Child>();
        _children.Add(new Child(this));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public bool Value
    {
        get => _value;
        set 
        {
            _value = value;
            PropertyChanged?.Invoke(new PropertyChangedEventArgs("Value"));
        }
    }
    private List<Child> _children    
}


public class Child
{
    public Child(Parent parent)
    {
        // Will failing to undo this with RemoveHandler cause a leak?
        PropertyChangedEventManager.AddHandler(r, OnValueChange, "Value");
    }

    void OnValueChanged(object sender, PropertyChangedEventArgs e)
    {
        // Do something...
    }
}

1 Ответ

1 голос
/ 04 апреля 2020

Ответ: нет.

Как следует из названия базового типа PropertyChangedEventManager (WeakEventManager), все обработчики, зарегистрированные в PropertyChangedEventHandler, будут сохранены как Слабые ссылки

Как вы, наверное, хорошо знаете,

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

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

RemoveHandler отсоединяет обработчик от события. Он удаляет запись из таблицы, которую поддерживает измененное свойство менеджера событий, чтобы отслеживать события и их обработчики.

В менеджере событий также есть процесс очистки для очистки всех записей, для которых был выбран целевой объект слабой ссылки. собранный G C.

Все это от реинжиниринга, начиная с: https://referencesource.microsoft.com/#windowsbase / Base / System / ComponentModel / PropertyChangedEventManager.cs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...