ThinkGeo.com    |     Documentation    |     Premium Support

Load map layers Asynchronously?

Is there currently a way to load the Map Layers with some sort of progress indicator while they are loading?  I previously (v2.0 and beta 1) was able to load the layers on a BackgroundThread even though it was not good practice it worked, now in beta 2 it's not working for me anymore so now i'm left with a long screen lag for users with no visual feedback that map layers are loading.  Is there any custom hook or way I can accomplish some sort of progress indicator?


Thanks, Chad



Chad, 
  
   I am not exactly sure I understand.  Do you want a progress indicator like a moving bar or a moving circle like in Ajax apps?  Also I am not sure I understand how you loaded the layers on a background thread in the 2.x stuff.  Can you enlighten me?  Can you explain a bit about how much data you are loading and how the loading times are?  I play with the new Desktop Edition and it is much more responsive than our 2.x version.  In the old version when you panned we refreshed the whole screen and everything locked up.  We also do the drawing in the 3.x on a seperate thread. 
  
 David

David,


Yeah, something as simple as an animated circle would suffice like an Ajax page.  The amount of data i load can be pretty large, we are doing mapping for local governement (primarly in the State of Michigan) and the layers we are typically showing are parcels and often aerial images as well (there can be 400k-500k parcels in a given County).  The aerial images (typically MrSid files) can be very large (> 1GB), so when loading those we can have lags of 4 +/- seconds on a good machine with a blank map.  Also when panning around at a further zoom, there is a blank screen while loading, then the map displays the layers again.  Having some sort of "loading..." or circle progess indicator during this time would be great, or even if you had some events where i could show my own such as "MapBeginLoading" and "MapEndLoading" that seems like it would work as well.


In the v2.0 stuff and 3.0 beta1 i was just using a BackGroundWorker thread then loading the map layers and calling refresh while on the background thread (in the DoWork event handler and showing a progress window until the WorkCompleted event fired) again... very sketchy doing this but never got any cross threading exceptions.


Also, now that the drawing is on a seperate thread i seem to be running into race condition issues, can you explain exactly how this is being done on another thread, like when is the other thread spawned and when is the drawing completed.  I now randomly get various exceptions when loading layers and refreshing the map and immediately trying to do something with the map after I add layers and call Map.Refresh().  Is there an event I can/should subscribe to to know when the async loading/drawing is completed.  I have a hard time specifically reproducing the problems consistently but at the lowest level of the stack traces on the exception it is always seems to be related to a thread and the top of the stack is always related to thinkgeo code which makes me think its a race condition and the drawing or loading just isnt completed yet.  Futher to sort of prove my theory i created a System.Timer object and don't do any logic until say 1 second after the a call to map.Refresh() after loading my layers and i get far less problems which again makes me think it's a race condition.  I never got these errors before with the exact same code in place and i think you guys just added the threading stuff i believe in beta 2.


Thanks,  Chad



Chad, 
  
   Thanks for the detailed response.  I will get the details on how the threading is done.  Also I will put in an issue to get some kind of loading image system put in.  I think this should be pretty easy, famous last words.  I am pretty sure we clone the layers and draw them on an alternate thread.  As it is a beta this is exactly the feedback we need.  We will put it through it’s paces with some larger datasets.  I think there are some optimizations we are working on for MrSids files.  how many seperate image files do you have or typically load?  how many of them are on the screen at any one time? 
  
 Please respond to this so it stays in my open queue. :-) 
  
 David

The "loading..." image or animated circlular progress indicator would be great, but is less big of  a deal than straightening out the race condition issues.  That is pretty important, i can see how if calling .Refresh() spawns a thread which is drawing/manipulating some behind the scenes UI stuff then i try to immediately access or manipulate layers or layer features on the main UI thread that could cause issues.  Also, for this particular set of map layers, the MRSid file i'm using is one real large file, not multiple small ones.  


I hope to hear back soon about how the threading is working and what it's doing so i can design around the current setup and move forward without randomly crashing.


Thanks, Chad



I've been hammering at it a little more and wanted to post 2 of exceptions i usually keep hitting often and randomly on initial load (there was 1 or 2 others that i cant get to happen at the moment).  Currently i'm loading 2 polygon layers and 2 line layers, thats it.  Both exceptions are in the MapSuiteCore 


1)  IndexOutOfRangeException:  Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.


2)  NotImplementedException:  This shape has not been implemented yet.


Stack Trace:


   at ThinkGeo.MapSuite.Core.xdad12102199d8695.x8c658393366f921d(Byte[] x1a22eb38b50994c5, Byte[] x1c828e238ef853a2, Int32 xedf77fd65cf83220)

   at ThinkGeo.MapSuite.Core.xdad12102199d8695.ReadRecord(Int32 recordIndex)

   at ThinkGeo.MapSuite.Core.ShapeFileFeatureSource.GetAllFeaturesCore(IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.ShapeFileFeatureSource.GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawingCore(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.ShapeFileFeatureSource.GetFeaturesForDrawingCore(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureLayer.DrawCore(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.Layer.Draw(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.DesktopEdition.LayerOverlay.xa6cb874f7090c07f(GeoCanvas x31c084515ae9393f)

   at ThinkGeo.MapSuite.DesktopEdition.LayerOverlay.DrawCore(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.Draw(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.xf0380b1a0bc40ca6.StartDraw()

   at ThinkGeo.MapSuite.DesktopEdition.x601a5561df898600.x7510a5c148e0acfd(Object x19b0b2213afc2289)

   at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)

   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)



David, I created a ticket through the Customer Portal to hopefully escalate these issues.  I'm having too many problems with beta 2 and they all seem to stem with the Threading stuff, i'm rolling back to beta 1 until these things get fixed. 


I discovered more issues such as when any map event handlers are called they are sometimes being called from another thread than the UI thread (verified by just checking Map.InvokeRequired and it' is == true ) which means anything you might try to do with the map is probably going to cause a problem and/or an exception.  This is sort of making sense now with how you described the layers are cloned then drawn on another thread, and while on the other thread, it's probably manipulating the staticLayers collection (causing some enumeration exceptions i've gotten), probably still firing the same events as it did when it was all being done on the UI thread (i.e. OverlayDrawn, etc...).


Anyways, I look forward to hearing from you guys and hope these issues get resolved quickly so i can move forward with your 3.0 tools.


Thanks,


Chad



Chad, 
  
 There is a known issue for the latest desktop edition that it will throw random exceptions on a Dual-Core system (while works fine on a Single-Core system) because of the threading conflicts. We are going to release a refresh in about 2 weeks without the threading temporarily so you can continue with your work; after we fix all the multithreading related issues then we turn it back. Sorry for the inconvenience and please let us know for any queries.  
  
 Ben 


Just to query, 
  
 In the OverlayDrawn event it isn’t thread safe. 
  
 I have a marquee progress bar that when the OverlayDrawing event is called it starts a little animation, then when the OverlayDrawn event fires it stops it. However the OverlayDrawn event is being called from another thread. 
  
 I assume you guys are on to it, just thought I would add that this is perfect example of a cross threading issue :)


 Michael, 
  
 Thanks for that example which will be very helpful for us to recreate this cross-threading issue. We will have a new release late this week or early next week in which multi-threading can be turned off. So please work with that version for now and we will keep working on the threading stuff. 
  
 Thanks, 
  
 Ben. 


I've been randomly getting those very same errors and it's driving me crazy as we're working on a release version of our software. 

NONE of our machines are dual processor however, nor do we implement ANY threading. 

However, I noticed that the map rendering seems to be in a thread, as it continues to update while my code is finished. 

Then when a user tries to do something that causes the map to update, it crashes with one of those errors. 

And if I ever called Map1.Refresh() one after the other, it would kill the application dead cold and no Try/Catch could contain it. 



The next release had better be more stable or I'll have an irate boss who wasn't too happy about the cost of the product to begin with. 

I'm sure the developers are working hard at it (aren't we all?) and I'm hoping for good things to come.



Kirk - I had to roll back to beta 1 and i'm still on it until they add an option (which is supposed to be soon) to turn off the threading.  I'm actually surprised anyone is able to use beta 2, it constantly would break for me and I couldn't continue using it. 



I put in a request to get Beta 1 (I only purchased at Beta 2). 
 Hopefully that will hold things together until the final release.

Uh Oh. 
 Can’t regress. 
 Using LayerOverlay and winformsmap.ZoomLevelSet which don’t exist in the previous Beta. 
  
 <sigh> 
  
 Guess I gotta wait for the next one, not that I have that kind of time on this project. 
  
 Oh well. It works 60% of the time if I click real slow…

Guys, 
  
 I’m very sorry about the cross threading issues. We released a new version (3.0.119) yesterday in which multi threading is by default turned off, can you try that one.   
  
 Thanks, 
  
 Ben 


Downloaded the Beta 2 #.199 and turned off the multithreading. 
  
 Although the rendering performance is of course significantly reduced, the application is rock solid and no longer throws a multitude of errors at every click. 
  
 We were even able to deploy a finalized Beta version to our guys in the field. 
  
 Thanks for releasing this temporary edition, and I look forward to a multithreaded version that will be as stable as the single thread.

Kirk, 
  
 Great it works for you. We still feel embarrassing to release that multi-threading one with so many cross threading issues. We will have thorough test when releasing the next multi-threading edition. Thanks for using our product and we will keep working hard and being better. 
  
 Thanks, 
  
 Ben