Рассмотрим сценарий объекта, который подсчитывает, как часто меняется какая-то наблюдаемая вещь. Существует два типа ссылок на объект: (1) ссылки на объекты, которые заинтересованы в подсчете; (2) те, которые используются наблюдаемыми вещами, которые на самом деле не заинтересованы в подсчете, но нуждаются в его обновлении. Объекты, которые заинтересованы в подсчете, должны содержать ссылку на объект, который в свою очередь содержит ссылку на объект, который управляет подсчетом. Сущности, которые должны будут обновить счетчик, но не заинтересованы в нем, должны просто содержать ссылки на второй объект.
Если первый объект содержит финализатор, он будет запущен, когда объект выйдет из области видимости. Это может привести к тому, что второй объект откажется от подписки, но, вероятно, он не должен быть отписан напрямую. Отказ от подписки, вероятно, потребует получения блокировки, и финализаторы не должны ждать блокировок. Вместо этого финализатор первого объекта, вероятно, должен добавить этот объект в связанный список, поддерживаемый с помощью Interlocked.CompareExchange, а некоторые другие потоки должны периодически запрашивать этот список для объектов, нуждающихся в подписке.
Примечание: между прочим: если первый объект содержит ссылку на второй объект, последний будет гарантированно существовать при выполнении финализатора для первого объекта, но он не будет гарантированно находиться в любом конкретное состояние. Нить очистки не должна пытаться с ней что-либо делать, кроме как отписаться.