A few tips for those using GeoCoordinateWatcher in Windows Phone 7.
- 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 …
- 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 !!