2010-09-13 63 views
0

我不确定标题是否足够,但这是我的问题:调试时消失COM对象

我有一个应用程序在.NET 4.0中使用一些COM对象写入。当我设置一个断点并检查我的代码太长时,当我尝试执行与COM相关的一行代码时,我得到一个异常。如果我相对快速地通过我的代码,一切都很好。

是否有一些开关来防止这种情况发生?什么导致了这种行为?

我得到的消息是InvalidCastException类型。

在此先感谢

+0

GC.KeepAlive是否使引用和底层COM对象保持活动状态? – 2010-09-13 10:06:23

+0

我还没有尝试过,但这意味着我必须为我的代码中的每个COM对象调用它。那是对的吗? – kamilw 2010-09-13 10:17:55

+0

尝试在一个孤立的部分,看看它是否在该地区有任何影响。 – 2010-09-13 10:30:05

回答

0

这些对象是远程还是本地?如果是远程的,也许你的断点触发RPC超时。

+0

不,这些对象是本地的。 – kamilw 2010-09-13 09:57:04

0

确定引用COM对象是否正确。否则,操作系统会发现COM对象不再被引用,从而将其从内存中释放。

+0

这是相同的代码。差异在于我如何快速通过代码 – kamilw 2010-09-13 10:00:17

1

当COM接口的IUnknown :: QueryInterface()方法返回E_NOINTERFACE错误返回码时,会引发InvalidCastException。这两个基本原因。通常的做法是,COM对象根本不会实现要投射到的接口。然而,这是非常可重复的,它不会受到调试会话的影响。

第二个原因更棘手,与线程有关。当您在另一个线程中使用RCW时,CLR将自动封送接口指针。这要求COM服务器要么显式地实现IMarshal接口,要么注册(从IDL构建的)代理/存根DLL或支持标准编组器(使用类型库)。

这不是普遍的做法,有许多COM服务器只是假设他们只能从单个线程使用。由于它在Watch窗口中评估表达式的方式,因此调试器开始播放。它实际上运行代码来获取表达式的值。确切的规则没有很好的记录,我知道,但有时代码将运行在辅助线程上。典型的例子是如果你使用Debug + Break All来分解程序。如果COM服务器不支持封送处理,那么该辅助线程将会炸弹。要检查的一件事是拥有COM对象的线程是当前线程。调试+ Windows +线程并双击拥有的线程(通常是您的应用的主线程)。

不是一个很好的解释,它不是你观察的扣篮,但我怀疑这是接近问题。您可以做的事情不多,避免使用Watch窗口显示COM服务器属性。或者编写一些调试代码将服务器属性复制到本地变量中,然后将Watch放在该变量上。

+0

我不必做任何事情。没有看窗口。没有评估。只需在断点处断开等一两分钟,然后按照COM对象命中F10即可。 – kamilw 2010-09-13 13:54:53

+0

不知道。至少发布一些代码行。 – 2010-09-13 14:10:55