Weird Errors popping up on a stable ArcObject extension

4028
6
03-04-2015 11:57 AM
TedKowal
Occasional Contributor III

A custom extension, that has existed many years, stable,.. all of a sudden started get weird errors.  Basically this extension takes a point snaps it to a corresponding LRS and retrieves an Offset, Measure, Side, and a segment ID from the Centerline.  The last time this extension was re-compiled was around ArcGIS 10.0.   I am currently running ArcGIS 10.2.2, the extension was performing fine .... the last successful run was month ago (Not something we run all the time).  No changes have been made to ArcGIS system.  The Window 7 system has only undergone bi weekly updates send out by microsoft. When I run the extension, I get two pop ups:

  1. "Item not found in this Collection"
  2. after clearing the above pop-up... "Objects in this Class cannot be updated outside an edit session"

The temporary work around is now run the extension after manually setting up an edit session ....  No edit session was ever required previously, last 7-8 years of use!

The exception is triggered on the pFeat.Store() execution.  "results" is a simple Collection .  The result collections contains all the correct information...pFeat is defined as an IFeature.

I suspect it has something to do with the Window system....Has anyone else experienced this? Any fixes?

'Return a cursor for all the features
      pCur = pFlayer.Search(Nothing, False)
      pFeat = pCur.NextFeature
      Do Until pFeat Is Nothing
         System.Windows.Forms.Application.DoEvents()
         Route = pFeat.Value(pFeat.Fields.FindField(fPointRouteName))
         'Get point to pass
         mypoint = pFeat.Shape
         Dim results As New Collection
         GC.Collect()
         System.Windows.Forms.Application.DoEvents()
         My.ArcMap.Application.StatusBar.StepProgressBar()
         results = getms(Route, mypoint)
         Try
         'Update fields
         If results.Item("SegID") = -9999 Then
            results.Remove("ErrDesc")
            results.Add("No Centerline SegID Found", "ErrDesc")
         End If
            pFeat.Value(pFeat.Fields.FindField("MP")) = results.Item("MS")
            pFeat.Value(pFeat.Fields.FindField("Offset")) = results.Item("OFFSET")
            pFeat.Value(pFeat.Fields.FindField("rSide")) = results.Item("rSide")
            pFeat.Value(pFeat.Fields.FindField("ErrDesc")) = results.Item("ErrDesc")
            pFeat.Value(pFeat.Fields.FindField("SegID")) = results.Item("SegID")
            pFeat.Store()
         Catch exp As Exception
            MsgBox(exp.Message)
         End Try
            pFeat = pCur.NextFeature
      Loop
0 Kudos
6 Replies
by Anonymous User
Not applicable

Hi Ted,

Its generally recommended that you do these sorts of updates within an edit session anyway, either manually or programmatically, just to trigger the events that other things may be listening to.

Has the data changed? versioned vs unversioned etc? does it participate in a relationship class? You'll need an edit session for those.

I'd also take out GC.Collect. You need a really good cause for using it in code these days.

TedKowal
Occasional Contributor III

Thanks for the reply...

To answer your questions:

  • has the data changed - The LRS/Route/Centerline No
  • version - No - -the version currently in production is about 2 years old and unchanged.
  • does it participate in a relationship class - No.

The only real change to our production environment are the windows system updates...(Which I believe is the trigger for the exception...which one I don't know)

This program is real old and the do events and the GC.Collect, at time,  was necessary because of "out of memory errors" on client machines.  By "sprinkling them in" -those old errors went away.  I will try and remove the GC collection to see if the "Not in collection" exceptions go away... worth a shot. 

I would rather not start an edit session if I do not have to.... the performance within an edit session is horrible -- it is very very very significantly faster outside.  Some large datasets can two days to process inside an edit session whereas only hours outside.  So I am treating the edit session as a temporary work around for now.

I will report back when I compile the changes...

Thanks for your reply!

0 Kudos
DuncanHornby
MVP Notable Contributor

Just been looking at your code. Why don't you use an update cursor instead of the store()? I've always understood store() is simple to use but had poor performance.

At some point in the past I picked up on the Using statement and ComReleaser and I now code using these. They are supposed to ensure the correct release of cursors, below is some sample code:

' For ArcGIS 10 using VS 2010 you need to import the following
Imports ESRI.ArcGIS.ADF.Connection.Local
Imports ESRI.ArcGIS.ADF


Dim pQueryFilter As IQueryFilter
pQueryFilter= New QueryFilterClass
pQueryFilter.WhereClause = "ID = 1"
Using releaser As New ComReleaser
  Dim pFeatureCursor As IFeatureCursor
  pFeatureCursor = pFeatureclass.Update(pQueryFilter, True)
  releaser.ManageLifetime(pFeatureCursor)
  Dim pFeature As IFeature
  pFeature = pFeatureCursor.NextFeature
  While pFeature IsNot Nothing
  ' Do something with pFeature
  pFeatureCursor.UpdateFeature(pFeature)
  pFeature = pFeatureCursor.NextFeature
  End While
End Using
TedKowal
Occasional Contributor III

At the time when it was written, Store() was the methodology and if my memory serves me correct, Nothing else worked with the memory problems except for sprinkling in the GC.Collect around until the memory issues went away (I did not understand nor currently understand fully the usage of GC.Collect).  Removing them (the memory problems come back?). I never revisited this program because I had no issues (If it is not broke don't fool around with it).  Assuming the memory issues are with the "releasing of the cursor", I like your code snippet!  However, I wonder if this would have anything to do with the "Item not found in the Collection" issue that has brought this to the front for discussion. I am being lazy and do not want to necessarily re-engineer the code again.  But in order to try out a few great ideas both you and Sean have have presented some refactoring of my logic in the code will have to occur....  This is turning out to be more of a challenge than a "Quick Fix."  -- I will keep you all abreast of my successes/(failures)  -- now I just need to carve out some time to work on this! 🙂

by Anonymous User
Not applicable

Duncan,

Just to comment on the search vs update cursor. A search cursor is generally preferred in ArcMap as it takes advantage of any spatial cache, particularly when enterprise GDB's are used. An update cursor will always do a DBMS read to get the row. However, this probably only matters in the real world when you have a large number of clients hitting the database.

There's some additional considerations in the help, updating features.

DuncanHornby
MVP Notable Contributor

Sean,

Thanks for the link to that page, useful stuff!

Duncan

0 Kudos