Question

I'm trying to create a background agent that periodically updates a user's Live Tiles on Windows Phone.

Currently, my code for the agent is:

    string where = "";
    private GeoCoordinate MyCoordinate = null;
    HttpWebResponse webResponse;
    ...
    protected override void OnInvoke(ScheduledTask task)
    {
        System.Diagnostics.Debug.WriteLine("Invoked");
        findMe();

        NotifyComplete();
    }

    private void ResponseCallback(IAsyncResult asyncResult)
    {
        HttpWebRequest webRequest = (HttpWebRequest)asyncResult.AsyncState;
        webResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult);

        MemoryStream tempStream = new MemoryStream();
        webResponse.GetResponseStream().CopyTo(tempStream);
    }

    private async void findMe()
    {
        Geolocator geolocator = new Geolocator();
        geolocator.DesiredAccuracy = PositionAccuracy.High;

        try
        {
            Geoposition currentPosition = await geolocator.GetGeopositionAsync(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10));

            MyCoordinate = new GeoCoordinate(currentPosition.Coordinate.Latitude, currentPosition.Coordinate.Longitude);

            // var uri = new Uri("http://www.streetdirectory.com//api/?mode=nearby&act=location&output=json&callback=foo&start=0&limit=1&country=sg&profile=template_1&x=" + MyCoordinate.Longitude + "&y=" + MyCoordinate.Latitude + "&dist=1");
            // var client = new HttpClient();

            var webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://www.streetdirectory.com//api/?mode=nearby&act=location&output=json&callback=foo&start=0&limit=1&country=sg&profile=template_1&x=" + MyCoordinate.Longitude + "&y=" + MyCoordinate.Latitude + "&dist=1");
            webRequest.BeginGetResponse(new AsyncCallback(ResponseCallback), webRequest);

            System.Diagnostics.Debug.WriteLine("findMe after response");
            System.Diagnostics.Debug.WriteLine(MyCoordinate.Latitude);
            System.Diagnostics.Debug.WriteLine(MyCoordinate.Longitude);
            // var response = await client.GetStringAsync(uri);
            System.Diagnostics.Debug.WriteLine(webResponse.ToString());

            JToken token = JArray.Parse(webResponse.ToString())[0];
            // JToken token = JArray.Parse(response)[0];
            var name = token.Next.First.First;
            var address = token.Next.Last.First;
            where = name + ", " + address;
        }
        catch (Exception)
        {
            System.Diagnostics.Debug.WriteLine("findMe died");
            where = "";
        }
        System.Diagnostics.Debug.WriteLine("findMe complete");
        UpdateAppTile();
    }

    private void UpdateAppTile()
    {
        System.Diagnostics.Debug.WriteLine("UpdateAppTile");
        ShellTile appTile = ShellTile.ActiveTiles.First();
        if (appTile != null)
        {
            StandardTileData tileData = new StandardTileData
            {
                BackContent = where
            };

            appTile.Update(tileData);
        }
        System.Diagnostics.Debug.WriteLine("Update Completed: " + where);
    }

When I attempt to run this, the code reaches webRequest.BeginGetResponse and subsequently stops. The next line, and ResponseCallback are not reached.

An older version of my code is commented out, which I thought was the problem but it experienced the same problem as well.

Was it helpful?

Solution

The problem is that you are calling NotifyComplete() before the callback returns.

By calling NotifyComplete you're telling the OS that you've finished all your work and the agent can be terminated. Obviously this isn't the case when you're waiting for your webrequest callback.

The simple solution is to move this call into the callback method. obviously you'll need to handle error exceptions and the request timeout taking longer than the agent will wait for as well though.

Changing to using awaitable code may make this easier for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top