我正在尝试诊断客户端崩溃,到目前为止我们无法在调试环境中重现。
我正在尝试确定如果没有附加调试器,CallbackOnCollectedDelegate
MDA通知(由第三方代码产生)是否会导致崩溃。
所以,问题是,第三方代码中导致回收代理的问题可能是导致此行为的原因 - 调试时MDA和不调用客户端崩溃吗?
有关此MDA的信息:http://msdn.microsoft.com/en-us/library/43yky316(v=vs.80).aspx
答案 0 :(得分:3)
如果您收到了MDA警告,那么您肯定会重新解决问题。是的,这将是一个没有调试器的硬崩溃,本机代码将在进行回调时轰炸。将调用从本机编码到托管代码的存根不再存在。 AVE的可能性很高,尽管从来没有100%保证,因为在收集存根后重新使用内存位置时可能会引用有效地址。随机代码执行就是失败模式。这两种结果都是过于丑陋而难以诊断的,从来没有让它走到这一步。
这是因为没有存储对传递给本机代码的委托的引用。或者不保持存储引用的对象存活,同样的事情。垃圾收集器无法查看并且不知道本机代码正在使用存根。实际上,CLR会在委托收集时销毁存根,这就是它如何管理存根的内存分配。
由您决定不会发生这种情况。最常用的解决方案是将委托对象引用存储在私有static
变量中。当您明确告知本机代码不再进行回调时,只将其设置回null
。永远不要将它设置为null是很常见的。在分配变量之前,还要添加一个测试以确保它为null,如果不是,则抛出InvalidOperationException。如果您需要额外的间接级别,请使用GCHandle.Alloc(Object)
。相同的食谱,在你知道它是安全的之前不要调用Free()。