Share via


GeoCoordinateWatcher tips part1

A few tips for those using GeoCoordinateWatcher in Windows Phone 7.

The data:

  • GeoCoordinateWatcher events fire in the UI thread.  Yes, StatusChanged and PositionChanged fire in the UI thread. 
    This is not due to thread affinity or any thing similar. Even if I start the GeoCoordinateWatcher in a background thread, it still fires events in the UI thread. They wanted to make it easy for developers.
     
  • GeoCoordinateWatcher PositionChanged will fire as often every second if you do not give it a MovementThreshold. Yes, you can not move at all and it is firing (on your UI thread).  Note, that is what I see on my phone, I do know the phone is optimized for battery life, so maybe it throttles with battery .. but when fully charged I see a ~1 Hz rate.
  • Getting a GPS fix out of GeoCoordinateWatcher can some times take a second or two. GPS is never a trivial operation (if you have ever turned it on in your car, I am sure you would know).  This can be a pain if you have an app that needs a fix in milliseconds, for example, if you are in search, and you want to do a local search, you want it to have ___location immediately, you don’t want to wait a second …

The Tips:

  • Avoid doing a lot of work on the GeoCoordinate events.  They are in the UI thread. Avoid as much work as you can (send to background thread if needed).
  • Absolutely set a MovementThreshold on the GeoCoordinateWatcher…   20 meters is probably lowest you should you.  I most often use 250m. Most of the services I use ( twitter, facebook, search, etc.  are doing searches in a > mile radius, 250m is great threshold for these services)…
    • if you do set MovementThreshold you should know that GeoCoordinateWatcher fires event in a weird order and the order can get you when you use MovementThreshold.
    • GeoCoordinateWatcher has a StatusChanged,  which you would expect fires when the GCW is ready…   my experience is that when subscribing to GCW I see this sequence
      • StatusChanged to Initializin
      • PositionChanged   -- with a valid ___location
      • StatusChanged to ready
      • If you have a high threshold, PositionChanged might not fire again…  so if you were a cautious developer and checked that Status is ready before accepting the ___location, you might not get a PositionChanged.   
    • The answer (from the devs) is that it is fair to assume that if PositionChanged fires, the status is ready.  It is OK to not check status in this event.
  • If  you read above, when there is no threshold it fires every second…  I am told the threshold does affect sampling rate (we are preserving battery as much as we can) but I am also thinking they are doing work sampling more often than most of my apps need.. I am not writing some thing that requires a position every few seconds..  so what I do for most of my apps is Start () and Stop () the GCW every 2 minutes (or longer pending on the app)…    Start and Stop is not an expensive operation…    Just have your GCW be wrapped by a singleton, and start it and stop it often..  Avoid calling Dispose () on GCW..    I have very seldomly (when stress testing) seen a race condition on Dispose () that could crash my app…   again, happens seldomly but I still don’t like the chances, since it is a singleton, and you can start and stop.. I don’t see a need to Dispose ()..

That should be all you need to really optimize your ___location-aware apps… Don’t forget to prompt the user before you use their ___location ..  
Feel free to beat me to the next part… you should know what that is..

Happy Windows Phone coding !!