ThinkGeo.com    |     Documentation    |     Premium Support

Overlay.Lock.EnterWriteLock()/Lock.ExitWriteLock()

Hi,


Overlay.Lock.EnterWriteLock()/ExitWriteLock() is new in RC1, what is the purpose of it? And what is the benifit of using it? I upgraded my product from previous beta release, and did not use this, it seems work. But I do notice some performance issue in this new release.


Rose


 


 



Rose,



  On thing ot make sure of is that you do not have the map in single threaded mode, this will cause some perfromance issues as it will only use one thread.  There is a property to check like Map1.ThreadingMode  If you have it multithreaded mode then the map should always be repsonsive.  We have added a bit of a delay before we draw and this is what you miht thing of as the performance issue as well.  The delay helps the overall performance though.  As you will notice as you re-visit parts of the map it is all cached and very fast.  I think the net was a big speed gain.



  In the RC1 we have re-introduced multi-threading however there is a little bit more you need to do.  Since we could be using an Overlay at the same time you are adding or modifying it we added an Overlay lock system. 

Whenever you want to modify an overlay, outside of the form load, you need to use the EnterWriteLock method on the Overlay.Lock property.  When you are finished you call the Overlay.Lock.ExitWriteLock.  I suggest you put the ExitWriteLock in the finally part of a try statement.  When you exit the write lock that is our cue that the Overlay is now dirty and we need to redraw it.  At the end just call Refresh() and we will handle the rest. 

 

  We updated our samples with this pattern and a good example is our RefreshPointsRandomly sample under the Dynamic Shapes branch.  in the sample code below is shows that we want to modify the items in the overlay and we enter the write lock and then when we are finsihed we exit the write lock.  This prevents the dsrawing thread from looping through that collection as we are modifying it.

 

  In the next day or two we will release a video to go over the new features and talk about this a little more in depth.  I am really sorry about the Redraw method not having an intuitive description on it.  We really did strive to make sure they all did.



David


 






            // Lock the overlay while we add the points   
            pointsOverlay.Lock.EnterWriteLock();   
            try  
            {   
                pointsLayer.InternalFeatures.Clear();   
                for (int i = 0; i < pointsCount; i++)   
                {   
                    PointShape pointShape = GetRandomPoint(pointsBoundary);   
                    string id = GetRandomDirection().ToString();   
                    Feature feature = new Feature(pointShape.X, pointShape.Y, id);   
                    pointsLayer.InternalFeatures.Add(feature);   
                }   
            }   
            finally  
            {   
                // Release the lock on the overlay   
                pointsOverlay.Lock.ExitWriteLock();   
            }   
  
            winformsMap1.Refresh();  


Rose, 
  
   I think we found the performance issue you mentioned.  We are creating a new build and will have it out in a few hours.  The issue is that internally we were opening and closing the layers on every drawing cycle.  There is no need for this, the layers can be left opened.  Closing and re-opening the layers has a big performance overhead. 
  
 David

David:


Based on what you are saying, we should call the Overlay.Lock.EnterWriteLock/ExitWriteLock only when we modify an overlay. But I noticed another refresh problem when I created the new overlay.  I opened a GeoTiff image first, then retrieved some data from PostgreSQL database and created a PostgreFeatureLayer, I set the map's extent to PostgreFeatureLayer's boundingbox, I can see the map's extent changed based on the boundingbox of the postgreFeatureLayer, but the PostgreFeatureLayer was not displayed, I had to zoom in to see the layer. My code worked very well in previous beta version.


We are anxiously waiting for the new release, every minute counts ,as we have already missed our project deadline!


Rose



Rose, 
  
  Did you call a Refresh after you added the new Overlay?  One thing you can try is to set the Overlay.Lock.IsDirty to true then call the refresh and see if that helps you.  If you can also details the step a little more clearly specifically when you call refresh and when you add the overlay to the map and when you add the layer to the overlay.  Adding a layer to an Overlay is considered changing it. 
  
   We are working as fast as possible.  Actually I just got the e-mail the latest build is now posted online.  Check it out.  It should help with the Closed problems.

David:


Thanks for your quick reply.


I have another question regarding to Overlay.Lock.EnterWriteLock/ExitWriteLock.


Again I am working on a PostgreFeatureLayer, when the user select an option to create a thematic map for the PostgreFeatureLayer, I put the code regarding to the style changes to the PostgreFeatureLayer in the Overlay.Lock.EnterWriteLock/ExitWriteLock, this works fine. But I also created a Lengend layer by extending the AdornmentLayer, and added it to AdornmentOverlay, if the user changes the thematic map option, I removed the legend layer from AdornmentOverlay and add a new one but with the same name, the problem is this legend layer is not refreshed, it worked in previous beta version.


The funny thing is if I put code which add the Legend layer to the AdornmentOverlay inside the PostgreFeatureLayer's Overlay.Lock.EnterWriteLock/ExitWriteLock block, this legend layer won't show up,.


Hope you can help on this.


Thanks


Rose


 



David:


I tried the latest build, the SQL Query on the PostgreFeatureLayer is much faster now, but the AdornmentOverlay is still not refreshed properly,I have to do sth on the map pan/zoom in/out to get the Legend layer refreshed.


Hope this help you to narrow down the problem


Rose



Rose,


To refresh the AdornmentOverlay, your code should be like this.



try
            {
                winformsMap1.AdornmentOverlay.Lock.EnterWriteLock();
               

                if (winformsMap1.AdornmentOverlay.Layers.Count == 1)
                {
                    winformsMap1.AdornmentOverlay.Layers.RemoveAt(0);
                }
                else
                {
                    MyAdornmentLayer layer = new MyAdornmentLayer();
                    winformsMap1.AdornmentOverlay.Layers.Add(layer);
                }
            }
            finally
            {
                winformsMap1.AdornmentOverlay.Lock.ExitWriteLock();
            }
            winformsMap1.Refresh();

And here attached is the complete test code.


Thanks,


Ben



722-5791Code.cs (2.25 KB)