.NET 确定性处置共享对象

.NET deterministic disposal of a shared object

当多个独立队列可能持有对同一托管对象的引用时,当所有队列都完成引用该对象时,确定性处置该对象的好方法是什么?

假设相关对象同时具有托管和非托管资源。

注意:在一个队列的出队函数中调用 Find() 函数来测试所有队列,这与我的想法不符。

如果消费者可以在他们应该调用的时候调用 Dispose,那么一个互锁的引用计数可能就足够了。如果它们不能,并且如果受保护的资源即使在仍在使用时被回收也不会损害安全性,则可以使用终结器来保护引用计数对象。如果在使用资源时回收资源可能会危及安全性,那么可能需要一个对象,该对象保留对该对象的所有使用者的长弱引用列表,并维护对该列表的静态引用。任何时候任何消费者被处置,或者终结器在守卫对象上触发,它应该(以线程安全的方式)检查所有弱引用并删除所有那些已经无效的引用或识别已经处置的对象。如果没有引用剩余,守卫对象应该使自己失效,移除对其弱引用列表的静态引用,并释放资源。如果守卫对象的终结器被触发但引用仍然存在(在某些复活场景中可能发生),它应该重新注册以完成。

请注意,虽然执行原子列表更新的常见模式是使用 CompareExchange 和对不可变列表的引用,但使用该技术需要将引用存储在除保护对象之外的其他内容中,存在静态引用。让静态引用标识守卫对象会使守卫对象的终结器变得无用,但如果没有对长弱引用列表的静态引用,将有可能使系统使引用无效,而由此标识的对象仍然存在并且可以复活。