Adding event handlers COM seperated from RCW

498
6
05-28-2013 01:20 PM
AlexanderGray
Occasional Contributor III
Hello Forum,

I have this intermittent problem, (happens about 60% of the time.) 
I have an extension (not addin) where I listen for a start editing event
In the start editing I start other events listeners, specificaly activeviewevents item added, item removed and mapevents featureclass changed.
The problem is often (60% of the time but never in debug mode) I get an exception when adding the event handler
System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.

this is a snippet in the startediting event handler
    
          m_actViewEvents = CType(m_map, IActiveViewEvents_Event)
          Trace.WriteLine("active view events retrieved")
          AddHandler m_actViewEvents.ItemAdded, AddressOf ItemAdded 'exception is thrown here
          Trace.WriteLine("item added event handler added")


I set the m_map in the start editing.  I tried casting the m_Editor.map to the Iactiveviewevents (better design), I tried setting the m_map from the editor, I tried using the document focus map.  I tried declaring the m_Editor and m_map member vars as shared (static)  I tried declaring the m_activeViewEvents as shared. 
As far as I know everything is done on the main thread.
I would rather not populate the m_map variable before the edit session is started since the focus map could change.
0 Kudos
6 Replies
RichardWatson
Frequent Contributor
Did you ever sort this out?
0 Kudos
AlexanderGray
Occasional Contributor III
not really.

I switched to populating the map with the document focus map on startup of the extension.  That works for my application, goodness forbids anyone adds a second map frame to the document...  Then it all falls apart.

I have the same problem with a task.  That is harder to fix because the only hook is the editor that gets passed in.  I had to get a reference to my application that has the map set on it.  It seems that getting the map from the editor in an event causes problems for setting further event handlers.

I really wish these things worked properly.  I can't really go to support because the problem is intermittant and part of a customization that has a few 10s of thousands of lines of code and tied to network resources...
0 Kudos
RichardWatson
Frequent Contributor
We also have the same intermittent problems.  I was hoping that you had figured it out:(
0 Kudos
JeffMatson
Occasional Contributor III
How are the event handlers being decremented? 
I have had problems in the past when AddHandler is called multiple times, but RemoveHandler is only called once. 



Hello Forum,

I have this intermittent problem, (happens about 60% of the time.) 
I have an extension (not addin) where I listen for a start editing event
In the start editing I start other events listeners, specificaly activeviewevents item added, item removed and mapevents featureclass changed.
The problem is often (60% of the time but never in debug mode) I get an exception when adding the event handler
System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.

this is a snippet in the startediting event handler
    
          m_actViewEvents = CType(m_map, IActiveViewEvents_Event)
          Trace.WriteLine("active view events retrieved")
          AddHandler m_actViewEvents.ItemAdded, AddressOf ItemAdded 'exception is thrown here
          Trace.WriteLine("item added event handler added")


I set the m_map in the start editing.  I tried casting the m_Editor.map to the Iactiveviewevents (better design), I tried setting the m_map from the editor, I tried using the document focus map.  I tried declaring the m_Editor and m_map member vars as shared (static)  I tried declaring the m_activeViewEvents as shared. 
As far as I know everything is done on the main thread.
I would rather not populate the m_map variable before the edit session is started since the focus map could change.
0 Kudos
AlexanderGray
Occasional Contributor III
RemoveHandler is being called in the stop editing event.

 Public Sub StopEditing(ByVal save As Boolean)
    Try

      If m_isInSaveEdit = False AndAlso _
        m_editor.EditWorkspace.Type = esriWorkspaceType.esriLocalDatabaseWorkspace Then

        RemoveHandler m_mapEvents.FeatureClassChanged, AddressOf FeatureClassChanged
        RemoveHandler m_actViewEvents.ItemAdded, AddressOf ItemAdded
        RemoveHandler m_actViewEvents.ItemDeleted, AddressOf ItemRemoved


        RemoveHandler m_IceLineObjectClassEvents.OnChange, AddressOf LineChange
        RemoveHandler m_IceLineObjectClassEvents.OnDelete, AddressOf LineChange

        RemoveHandler m_IcePointObjectClassEvents.OnChange, AddressOf PointChange
        RemoveHandler m_IcePointObjectClassEvents.OnDelete, AddressOf PointChange
        RemoveHandler m_AOIObjectClassEvents.OnDelete, AddressOf AOIDelete
        RemoveHandler m_AOIObjectClassEvents.OnCreate, AddressOf AOICreate

        DisableDockEditorWindows()
      End If

        Catch ex As Exception
      Trace.WriteLine(ex)
    End Try
  End Sub
0 Kudos
JeffMatson
Occasional Contributor III
I see two possibilities that would lead to the same problem I was having:

1)  AddHandler for one or more events is being called multiple times, but only removed once.
2)  AddHandler is called once, but something happens causing StopEditing() to not be hit.

In either case it might leave you with "orphaned" subscribers.
For #1 you can keep track of the number of times AddHandler is called, then loop to call RemoveHandler the same number of times. 
For #2 you might try putting the RemoveHandlers in their own procedure where it can be called from StopEditing and the extension shutdown to make sure it happens.




RemoveHandler is being called in the stop editing event.

 Public Sub StopEditing(ByVal save As Boolean)
    Try

      If m_isInSaveEdit = False AndAlso _
        m_editor.EditWorkspace.Type = esriWorkspaceType.esriLocalDatabaseWorkspace Then

        RemoveHandler m_mapEvents.FeatureClassChanged, AddressOf FeatureClassChanged
        RemoveHandler m_actViewEvents.ItemAdded, AddressOf ItemAdded
        RemoveHandler m_actViewEvents.ItemDeleted, AddressOf ItemRemoved


        RemoveHandler m_IceLineObjectClassEvents.OnChange, AddressOf LineChange
        RemoveHandler m_IceLineObjectClassEvents.OnDelete, AddressOf LineChange

        RemoveHandler m_IcePointObjectClassEvents.OnChange, AddressOf PointChange
        RemoveHandler m_IcePointObjectClassEvents.OnDelete, AddressOf PointChange
        RemoveHandler m_AOIObjectClassEvents.OnDelete, AddressOf AOIDelete
        RemoveHandler m_AOIObjectClassEvents.OnCreate, AddressOf AOICreate

        DisableDockEditorWindows()
      End If

        Catch ex As Exception
      Trace.WriteLine(ex)
    End Try
  End Sub
0 Kudos