Select to view content in your preferred language

COM object that has been separated from its underlying RCW cannot be used.

6252
11
Jump to solution
09-06-2018 02:23 AM
Harald_ØysteinLund1
Esri Contributor

Hi, 

I have created a EditorExtention in a ArcMap C# Add-in. Here I hook up to editor events like OnStartEditing, OnStopEditing OnCteateFeature etc.

I also wan't to listen to the OnBeginreconcile event to prevent the user to post incomplete data. This I have managed to obtain and it works well using editing tools, reconcile and undo the reconcile if the data isn't valid.

For one edit task, we have set up a editing window to create a complex feature, a lighthouse with sectors. To run this task, Editing has to be started by the user with standard ArcMap tools, and a lighthouse has to be created, also with standard tools. The lighthouse has to be selected, and the user clicks; a button to open the custom Sector Editing window. In the StartEditing event we hookup to the OnReconcile and OnBeginReconcile events with the following Code:

private IVersionEvents2_Event VersionEvents2
 {
 get {
 return ArcMap.Editor.EditWorkspace as IVersionEvents2_Event; 
 }
 }

private IVersionEvents_Event VersionEvents
 {
 get
 {
 return ArcMap.Editor.EditWorkspace as IVersionEvents_Event;
 }
 }


void Events_OnStartEditing()
 {
 

//Wire OnCreateFeature edit event.
 Events.OnCreateFeature += new IEditEvents_OnCreateFeatureEventHandler
 (Events_OnCreateFeature);
 //Wire onChangeFeature edit event.
 Events.OnChangeFeature += new IEditEvents_OnChangeFeatureEventHandler
 (Events_OnChangeFeature);
 //Wire onChangeFeature edit event.
 Events.OnDeleteFeature += new IEditEvents_OnDeleteFeatureEventHandler 
 (Events_OnDeleteFeature);
 Events2.OnSaveEdits += new IEditEvents2_OnSaveEditsEventHandler(Events_OnSaveEdits);
 Events2.OnStartOperation += new IEditEvents2_OnStartOperationEventHandler(Events_OnStartOperation);
 //VersionEvents2.OnPost += new IVersionEvents2_OnPostEventHandler(Events_OnPost); 
 Events2.OnStopOperation += new IEditEvents2_OnStopOperationEventHandler(Events_OnStopEditOperation);
 VersionEvents2.OnBeginReconcile += new IVersionEvents2_OnBeginReconcileEventHandler(Events_OnBeginReconcile);
VersionEvents.OnReconcile += new IVersionEvents_OnReconcileEventHandler(Events_OnReconcile);
 WiredUp = true;
 
 }

When the user describe each sector in this customized window with database grid window and click the window's save button, the following process is run:

StartEditingOperation

   Create the new sectors and related them to the selected lighthouse

   Update any existing sectors.

StopEditingOperation

StartEditingOperation

   Delete those sectors that is deleted.

StopEditingOperation

StartEditingOperation

   Create glass information for each sectors if the user has filled out this information

   Relate the glass info to each sector.

StopEditingOperation

User close the window.

I the user clicks reconcile, the event OnBeginReconcile should fire, and that happens most of the times when I run the testes. But some times the PostButton is enabled and no the event code we have created does not execute.

When the user clicks StopEditing and we then have to unwire the events, the following code fails:

VersionEvents2.OnBeginReconcile -= new IVersionEvents2_OnBeginReconcileEventHandler(Events_OnBeginReconcile);
VersionEvents.OnReconcile -= new IVersionEvents_OnReconcileEventHandler(Events_OnReconcile);

The error that is casted:

COM object that has been separated from its underlying RCW cannot be used.

So doing editing by the book calling start and stop editioperation and only calling System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) for ICursor objects, we get this behavior some times, and some times not.

I have even got VersionEvents2.OnBeginReconcile -= new ... line to run ok, but the next line fails. This is very odd since the pointers point to the same object!?

So the reason that the event isn't always caught by our code, is the the COM object has been separated from its underlying RCW.

Now the question: Do ESRI run any marshal releasecomobject that on the EditWorkspace object and the GC destroys the object. 

I've done some changes in the process/code to see if I could simplify the processes and I have also read through the code to see if I do some releasecomobject where I shouldn't.

  1. Made one StartEditOperation ans StopEditOperation for the whole save process for the Sector editing.
  2. Uncommented the function that run the System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) to make sure it isn't called at all by my code.
  3. Also tried to do the editing without Start and Stop editoperation, but that gave another error not related to this at all.
  4. On the windows closing I have tried to unwire and wire up the events, but here it fails with the same error message, COM separation.

So nothing helps. Is this a bug? I haven't stripped this down to a small add-in to see if I could reproduce the error in a smaller scale. That maybe my next approach. It seems that the ArcMap.Editor.Editworkspace is release.

It doesn't get fixed even when we try to stop and start  the editing again. Looks like ArcMap.Editor.EditWorkspace is lost.

Maybe I could try to reconnect to he application, but I don't believe that would help, since we're just pointing to a active arcmap application.

Any one that has experienced this?

 

0 Kudos
11 Replies
JeffMatson
Occasional Contributor III

I think you'll want to set up your event using a variable:

ArcObjects 10 .NET SDK Help 

I've also utilized a counter to help avoid RCW errors when deprecating event listeners:

private void SetupCoreFrameworkMapEvents()
{
if (m_application.Document.Parent is IMxApplication && m_sbRefs_MapEvents == 0)
{

m_VersionChanged = new CoreFramework.FrameworkVersionChangedEventHandler
(WaterEditorExtension_ExtensionVersionChanged);
m_coreFramework.FrameworkVersionChanged += m_VersionChanged;

m_sbRefs_MapEvents += 1;
}
}

private void RemoveCoreFrameworkMapEvents()
{
while (m_sbRefs_MapEvents > 0)
{
if (m_VersionChanged != null) { m_coreFramework.FrameworkVersionChanged -= m_VersionChanged; }
m_sbRefs_MapEvents -= 1;
}
}

Harald_ØysteinLund1
Esri Contributor

Hi Jeff,

Thanks, I believe this is the same as Gintautas suggested. I will change my code to store the Editworkspace in a variable and hook up to the events through that object.

0 Kudos