ConditionalWeakTable по-прежнему содержит ссылки, которые должны быть собраны GC? - PullRequest
0 голосов
/ 17 января 2019

Я использую ConditionalWeakTable с целью свободного хранения ссылок вместо строгих ссылок с использованием традиционного поиска, подобного Dictionary. Однако я проверил один случай, чтобы дважды проверить эту возможность и похоже, что она не удалась. Следующий код основан на Windows Forms, однако вы можете попробовать настроить его, используя любую платформу или платформу:

Образцы моделей :

public class SampleModel : INotifyPropertyChanged {
   public event PropertyChangedEventHandler PropertyChanged;
   protected void OnPropertyChanged([CallerMemberName] string property = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
    string _name;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if(_name != value)
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    }
}

Основной код :

//at some class level scope
BindingSource _bs;
ConditionalWeakTable<BindingSource, object> _lookup = 
                          new ConditionalWeakTable<BindingSource, object>();

public void Test(){
   _bs = new BindingSource();
   var item = new SampleModel();
   _bs.Add(item);
   _bs.ListChanged += (s,e) => 
   {
      MessageBox.Show("Failed! There is some memory leak");
   };
   _lookup.Add(_bs, new object());
   //here the old instance is not referenced by any variable
   _bs = new BindingSource();
   //try collecting all collectable things
   GC.Collect();
   GC.WaitForPendingFinalizers();
   //try changing the item's property
   //the old instance of BindingSource if not collected will still 
   //fire the ListChanged event and the handler will show a message box 
   //as you see above.
   item.Name = "some name";
}

Приложение тестирования встроено в режим выпуска, чтобы обеспечить правильную работу ГХ. И в результате окно сообщения всегда показывает. Ожидаемый результат - окно сообщения не отображается. Обратите внимание, что метод Test запускается только один раз для каждого запуска приложения тестирования.

Не могли бы вы объяснить, что-то здесь не так?

...