Можно ли создать по-настоящему слабый словарь в C#?
Я пытаюсь выяснить детали для истинного WeakKeyedDictionary<,>
для C#... но я сталкиваюсь с трудностями.
Я понимаю, что это нетривиальная задача, но кажущаяся неспособность объявить WeakKeyedKeyValuePair<,>
(где GC только следует за значением, если ключ достижим) делает это на первый взгляд невозможным.
Я вижу две основные проблемы:
Каждая реализация, которую я до сих пор видел, не обрезает значения после того, как ключи собраны. Подумайте об этом - одна из главных причин использования такого словаря состоит в том, чтобы не допустить хранения этих значений (а не только ключей!), Поскольку они недоступны, но здесь они оставлены указанными сильными ссылками.
Да, достаточно добавить / удалить из Словаря, и они в конечном итоге будут заменены, но что если вы этого не сделаете?
Без гипотетического
WeakKeyedKeyValuePair<,>
(или другое средство указания GC пометить значение, только если ключ достижим), любое значение, относящееся к его ключу, никогда не будет собрано. Это проблема при хранении произвольных значений.
Проблема 1 может быть решена довольно неидеальным / хакерским способом: используйте GC-уведомления, чтобы дождаться завершения полного GC, а затем продолжайте и сокращайте словарь в другом потоке. С этим я в порядке.
Но проблема 2 поставила меня в тупик. Я понимаю, что этому легко противостоит "так не делай этого", но меня удивляет - можно ли вообще решить эту проблему?
1 ответ
Посмотрите на класс ConditionalWeakTable
Позволяет компиляторам динамически присоединять поля объекта к управляемым объектам.
По сути, это словарь, в котором ключ и значение являются WeakReference, а значение сохраняется, пока ключ активен.
Заметка! Этот класс не использует GetHashCode
а также Equals
чтобы сделать сравнения равенства, он использует ReferenceEquals
,