.net 处理COM事件时出现TargetInvocationException异常

.net 处理COM事件时出现TargetInvocationException异常,.net,vb.net,events,com,.net,Vb.net,Events,Com,我正在开发一个COM dll库,我有一个小小的vb.net(VS2005)应用程序来测试它 我在应用程序中声明了我的对象为 私有m_VarName作为MyLib.CMyComClass 到目前为止,一切顺利 但是现在,我需要一个事件来通知应用程序一些事情,所以我在COM dll中实现了这样的事件,并将声明更改为 Private with events m_VarName作为MyLib.CMyComClass 到目前为止,一切都很好。但如果我添加一个子系统来处理我的事件: 私有子m_VarName

我正在开发一个COM dll库,我有一个小小的vb.net(VS2005)应用程序来测试它

我在应用程序中声明了我的对象为

私有m_VarName作为MyLib.CMyComClass

到目前为止,一切顺利

但是现在,我需要一个事件来通知应用程序一些事情,所以我在COM dll中实现了这样的事件,并将声明更改为

Private with events m_VarName作为MyLib.CMyComClass

到目前为止,一切都很好。但如果我添加一个子系统来处理我的事件:

私有子m_VarName_OnCaptureStop()处理m_VarName.MyEvent

端接头

第一次创建对象时,没有发生什么不好的事情,但是如果我重新实例化它

如果(非m_VarName为Nothing),则释放对象(m_VarName)

m_VarName=新的MyLib.CMyComClass

然后我得到了一个神秘的targetingException,似乎与反射有关(好吧,我没有使用反射)

如果我删除“Handles m_VarName.MyEvent”部分,一切似乎都正常。如果有关系的话,我现在不会发射任何事件。
知道为什么会发生这种情况吗?

原因与VB.Net中的
with events
Handles
的实现有关。当您在VB.net中使用
WithEvents
修饰符声明字段时,它将作为属性生成

每当通过赋值操作更新该属性时,属性设置程序将从旧事件处理程序中取消订阅,然后在新值上订阅事件处理程序。实际上是这样的

Property m_VarName as SomeType 
  Set   
    if _m_VarName isNot Nothing Then
      RemoveHandler _m_VarName.SomeEVent,m_VarName_OnCaptureStop
    End If
    _m_VarName = Value
    AddHandler _m_VarName.SomeEvent,m_VarName_OnCaptureStop
  End Set 
End Property

如果你认为在代码的上下文中,本质上发生的是下面的

ReleaseComObject(m_VarName)
RemoveHandler m_VarName.SomeEvent,m_VarName_OnCaptureStop
因此,您正在对已发布的COM对象调用
RemoveHandler
。因此,它抛出一个
异常


修复很简单,不要调用
ReleaseComObject
。实际需要调用此方法的情况非常少,几乎可以肯定不适用于这种情况。而是让GC正常地收集它

我认为有必要调用ReleaseComObject。我刚刚在MSDN中看到,它只是在我需要以某种特定顺序释放对象时才会出现。非常感谢您提供如此详细的答案,我刚刚测试了它,它可以工作。+1,同意。ReleaseComObject()是毒药。信任垃圾收集器。