2010-08-31 36 views
1

我正在開發一個COM DLL庫,並且我有一個小vb.net(vs 2005)應用程序來測試它。TargetInvocationException在處理COM事件時

我在應用程序中聲明我的對象

私人m_VarName作爲MyLib.CMyComClass

到目前爲止,一切都很好。

但現在,我需要一個事件來通知一些事情的應用程序,所以我實現了在COM DLL這樣的事件,並改變了聲明

私人WITHEVENTS m_VarName作爲MyLib.CMyComClass

到目前爲止,再次如此好。但是,如果我添加子來處理我的事件:

私人小組m_VarName_OnCaptureStop()處理m_VarName.MyEvent

...

末次

我第一次創建該對象,沒有什麼不好發生,但如果我重新實例它

如果(不是m_VarName什麼)然後ReleaseComObject的(m_VarName)

m_VarName =新MyLib.CMyComClass

然後我得到一個神祕的TargetInvocationException,看似與反射(其中,據我所知,我沒有使用)。

如果我刪除「處理m_VarName.MyEvent」部分,一切似乎工作。如果重要的話,我現在不會發射任何事件。 有關爲什麼發生這種情況的任何想法?

回答

2

爲什麼要在VB.Net中執行WithEventsHandles。當您在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 。因此它會拋出一個Exception

修復很簡單,不要撥打ReleaseComObject。實際需要調用此方法的情況很少,幾乎肯定不適用於這種情況。而是讓GC正常收集。

+0

我認爲有必要調用ReleaseComObject。 我剛剛在MSDN中看到,它僅在需要以特定順序發佈對象的情況下才有。 非常感謝您提供這樣一個詳細的答案,我剛剛測試過它,它的工作原理。 – raven 2010-08-31 16:53:55

+0

+1,表示同意。 ReleaseComObject()是毒藥。相信垃圾收集器。 – 2010-08-31 16:55:14