Bog'liq CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C
Глава.21 .Автоматическое.управление.памятью.(уборка.мусора)
public delegate TValue CreateValueCallback(TKey key); // Вложенное
// определение делегата
}
Для связи произвольных данных с одним или несколькими объектами класса
для начала вам потребуется экземпляр этого класса. Затем следует вызвать метод
Add
, передав параметру
key
ссылку на объект, а параметру
value
— данные, которые
вы хотите связать с этим объектом. При попытке повторного добавления ссылки
на тот же самый объект метод
Add
выдаст исключение
ArgumentException
. Чтобы
изменить связанное с объектом значение, нужно удалить ключ и добавить его снова
уже с другим значением. Имейте в виду, что так как класс является безопасным
в отношении потоков, его могут в конкурентном режиме использовать другие
потоки, хотя это не лучшим образом сказывается на производительности. Произ-
водительность класса нужно проверять, чтобы узнать, насколько она достаточна
именно для вашего сценария.
Разумеется, во внутренней реализации таблицы хранится ссылка
WeakReference
на объект, переданный им в качестве ключа; это гарантирует, что таблица не бу-
дет принудительно увеличивать время жизни объекта. Но особенность класса
ConditionalWeakTable
состоит в том, что он гарантирует наличие в памяти значения
до тех пор, пока объект идентифицируется в памяти по ключу. Это превосходит
способности обычного класса
WeakReference
, в котором значение уничтожается
уборщиком мусора, хотя ключ еще существует. Класс
ConditionalWeakTable
мо-
жет применяться для реализации механизма свойств зависимости, используемого
в XAML. Он может также внутренне использоваться в динамических языках для
динамической связи данных с объектами.
Далее показан код, демонстрирующий применение класса
ConditionalWeakTable
.
Он позволяет вызывать метод расширения
GCWatch
для любого объекта, передавая
в него некий тег
String
. В результате при уничтожении объекта в ходе уборки
мусора вы получаете извещение через консоль:
internal static class ConditionalWeakTableDemo {
public static void Main() {
Object o = new Object().GCWatch("My Object created at " + DateTime.Now);
GC.Collect(); // Оповещение об отправке в мусор не выдается
GC.KeepAlive(o); // Объект, на который ссылается o, должен существовать
o = null; // Объект, на который ссылается o, можно уничтожать
GC.Collect(); // Оповещение об отправке в мусор
Console.ReadLine();
}
}
internal static class GCWatcher {
// ПРИМЕЧАНИЕ. Аккуратнее обращайтесь с типом String
// из-за интернирования и объектов-представителей MarshalByRefObject
private readonly static ConditionalWeakTableNotifyWhenGCd> s_cwt =
new ConditionalWeakTable