我的情况是,我有一个包含 HGLOBAL 和 List<Delegate> 的 ac# 对象。HGLOBAL 持有对委托的引用,并且 HGLOBAL 在非托管代码中注册为回调(特别是 vtbl 样式的接口)。
我试图不陷入整体设计的细节中(我已经期待那些理解我在上一段中所做的事情的人会尖叫)。我的问题目前是使用我希望以不同方式记录的功能的生命周期管理之一。
我已经将持有 HGLOBAL 和 List<Delegate> 的类转换为 SafeHandle 的子类(因为 CriticalFinalizerObject 并且因为 HGLOBAL 有点像句柄),并且我确实有使用CER 样式的原子事务来实例化它的类来通知C# 当非托管代码不再期望它继续存在时。
调用 DangerousAddRef 是否有效地增加了整个 SafeHandle 对象的引用计数?List<Delegate> 是否会包含在此引用计数中?另一种问这个问题的方法是,DangerousAddRef 是否有效地为整个 SafeHandle 对象构造了GCHandle,或者它是否只是对内部的 SafeHandle.handle 成员这样做?
如果它不适用于整个对象,则 List<Delegate> 可能会被提前收集,并在非托管代码尝试调用它时导致访问冲突。
如果它作为一个整体应用于对象,那么我刚刚在垃圾收集堆中创建了一个引用计数对象块,我最好确保我没有创建任何引用循环。
我怀疑是后者,但是在这种东西上很少有谷歌搜索,当你处理的唯一症状是进程关闭时终结器线程的非托管访问冲突,而没有运行实际的托管代码,然后它开始很难看出你是否朝着正确的方向前进。