GraphicTracker fails with AccessViolationException

2119
34
Jump to solution
02-27-2013 04:52 AM
DavidClarke1
New Contributor III
I am developing an application using the GraphicTracker to display moving icons.  I am using the Windows.Forms.Timer event to suspend the display updates for two seconds.  I have another couple subroutines that creates and removes GraphicTrackerSymbols to the tracker.  All this happens on the same thread as the Windows.Forms.Timer does excute on the main gui thread.  I have also verified this in debug.

Every so often the program will crash with an AccessViolationException while trying to set the GraphicTracker.SuspendUpdate property to FALSE; it ALWAYS fails on trying to set that property to "FALSE".  What I noticed was that if I do not remove any items from the GraphicTracker it does not fail.  When I am removing items here and there as needed at some point it will fail.  It may be 30 seconds or 2 minutes.  I use the exact same test data (geometry/symbols/coordinates) but it still fails at some "random" time.  The map no longer updates on the screen and the whole map is unusable.  I cannot seem to recover or continue on.  Catching the exception makes no difference as the map just will not work anymore.

Here is the timer code.  The timer itself is set to run every 2 seconds.

_gt.SuspendUpdate = False System.Threading.Thread.Sleep(300) _gt.SuspendUpdate = True


My thoughts are that there is some timing issue while using the "Remove" method on the GraphicTracker object that conflicts with the "SuspendUpdate" property.  I have tried setting the timer to be a longer or shorter interval and also changing the "Sleep" interval but nothing seems to help.
0 Kudos
1 Solution

Accepted Solutions
DavidClarke1
New Contributor III
I just received this from ESRI support.

NIM079055 - AccessViolationException when IGraphicTracker::Add is used to add many GraphicTrackerSymbols based on a PictureMarkerSymbol.

View solution in original post

0 Kudos
34 Replies
LeoDonahue
Occasional Contributor III
When I read the Java docs on GraphicTracker, it says the suspendupdate property is false by default.


public boolean isSuspendUpdate()                         throws IOException,                                AutomationException

Disables automatic refreshing of the display until unsuspended or until the  display is explicitly refreshed. Suspending automatic refresh is ideal before  bulk updates.

Description
Suspends update (i.e refresh) of the  display. This property is false by default. This means the GraphicTracker will  automatically refresh the display after each graphic is changed.
Setting this property to true, moving the  graphics and then setting this property to false will result in one refresh call  and will draw all graphics at once. In an dynamic map, this property is not  relevant.
0 Kudos
DavidClarke1
New Contributor III
You are correct. It is FALSE by default.  However, the toggling of that property is on a Windows.Forms.Timer so that it executes every 2 seconds.  That way the screen is not updating for every item I move on the screen.  In production I will be receiving a continuous stream of GPS data; at this point I am simulating that.  Because I am receiving a continuous stream of GPS data, I do not want the screen (via GraphicTracker) to update for every item; the CPU usage would be too high.  If I delay by 2 seconds and only allow the screen to update every 2 seconds (via timer) then the CPU is manageable and everything is great, until the error.

Keep in mind this code executes a hundred or even a few thousand times before it fails.

There is an option to run this in Dynamic Display mode which would not require the timer and the CPU would be just a few percent but it is totally useless; there are several bugs and "limitations" when using Dynamic Display which do not allow me to do the things I need to do.
0 Kudos
JasonPike
Occasional Contributor
I am developing an application using the GraphicTracker to display moving icons.  I am using the Windows.Forms.Timer event to suspend the display updates for two seconds.  I have another couple subroutines that creates and removes GraphicTrackerSymbols to the tracker.  All this happens on the same thread as the Windows.Forms.Timer does excute on the main gui thread.  I have also verified this in debug.

Every so often the program will crash with an AccessViolationException while trying to set the GraphicTracker.SuspendUpdate property to FALSE; it ALWAYS fails on trying to set that property to "FALSE".  What I noticed was that if I do not remove any items from the GraphicTracker it does not fail.  When I am removing items here and there as needed at some point it will fail.  It may be 30 seconds or 2 minutes.  I use the exact same test data (geometry/symbols/coordinates) but it still fails at some "random" time.  The map no longer updates on the screen and the whole map is unusable.  I cannot seem to recover or continue on.  Catching the exception makes no difference as the map just will not work anymore.

Here is the timer code.  The timer itself is set to run every 2 seconds.

_gt.SuspendUpdate = False
System.Threading.Thread.Sleep(300)
_gt.SuspendUpdate = True


My thoughts are that there is some timing issue while using the "Remove" method on the GraphicTracker object that conflicts with the "SuspendUpdate" property.  I have tried setting the timer to be a longer or shorter interval and also changing the "Sleep" interval but nothing seems to help.


There are definitely some problems with the GraphicTracker. I would look at this thread:
http://forums.arcgis.com/threads/72516-Memory-Leak-with-Graphic-Tracker

Also, if you want to find out where the access violation is occurring (to provide ESRI with more information if you file a case) you can use WinDbg and/or Application Verifier:
http://forums.arcgis.com/threads/75186-Memory-leak-with-FeatureClass-object?p=266132#post266132
0 Kudos
DavidClarke1
New Contributor III
I actually saw that thread when I did my initial scan of the ESRI forums looking for answers.  For a long while I couldn't reproduce it very well until I figured out removing items from the GraphicTracker triggers it (more often than not).  It is still variable the number of deletes before it fails.  I will take a look at WinDbg.

Most likely I will report this to ESRI since I am unable to fix this.  Unless someone has an idea for me to try (I'm out of ideas).
0 Kudos
LeoDonahue
Occasional Contributor III
David,

Are you doing it backwards?

The Java docs I posted said start with true, do stuff, then set it to false.

Your code is the opposite.

_gt.SuspendUpdate = False 
System.Threading.Thread.Sleep(300) 
_gt.SuspendUpdate = True
0 Kudos
DavidClarke1
New Contributor III
What I am doing causes the screen to only update every 2 seconds which gives me good performance.
What you are suggesting will cause the screen to update FOR 2 seconds then briefly pause.

I hope this makes sense.
0 Kudos
LeoDonahue
Occasional Contributor III
Sorry for the confusion David,

Perhaps I'm not getting it either.

When I read the docs, suspend update by default is false, which means as graphics are added or moved or removed, the automatic refresh will occur.  I'm stating that from the docs. 

Suspending the automatic update, by setting it to TRUE, is what you want for bulk updates.  Right?  Am I misreading that?

You want to suspend the automatic refresh, add some Graphic Tracker geometry, symbols, etc, then unsuspend the automatic refresh of GraphicTracker, which will refresh your display.  Then you want to suspend it again while there are more things to add, then unsuspend, etc.

Are you doing a partial refresh of IActiveView?
0 Kudos
DavidClarke1
New Contributor III
You are reading the documentation perfectly, that is exactly how I understand it as well.  I first tried that without success in terms of performance.

You are talking about bulk updates which are different than my continuous stream of data coming in to the application.  For my application, I will constantly receive one GPS coordinate at a time (very fast though)

In a sense I am doing what you suggest: for 2 seconds my application is suspending the updates to the screen.  During that time I could have received 10 (as a guess) GPS coordinates which are processed by the GraphicTracker with the display still suspended.  Now the timer kicks off and I set the property to FALSE allowing the GraphicTracker to update the screen with my 10 updates.  After that and a 300 ms sleep, I set the property to TRUE to stop updating the screen for another 2 seconds.  This repeats giving me the performance I need in terms of CPU usage.

If I was receiving 10 or so transactions (all at once) every few seconds then I think the method you describe would work great for me.  But I am getting these transactions fast but one at a time.

One more thing, I originally tried saving up the GPS coordinates I was receiving into a queue and then doing exactly as you suggest to process them in a bulk manner.  However, depending on my circumstances I may not always have a continuous stream of data coming in.  So then I would be waiting for a queue to fill up when it may take 10 minutes.  I suppose I could try to make a hybrid with a queue while also checking elapsed time.

I have to repeat that this code works for 15 seconds or 10 minutes before failing; I use the same data every time.
0 Kudos
LeoDonahue
Occasional Contributor III
How often does your GPS device poll?

I can't think of another way to manually test this than to create a tool add-in that lets me suspend the GraphicTracker, then click,click,click as fast as I can in the map, store those locations in a GraphicTracker then use a timer to unsuspend the GraphicTracker after 2 or 3 seconds, which should refresh my display.

Now, depending on my zoom scale and how many other layers I'm displaying and what kind of symbols I'm using to display the graphics, i can't help but think at some point the GraphicTracker refresh could take longer than normal.

Approximately how many graphics have you added to your GraphicTracker object before everything goes bust?
0 Kudos