Search code examples
c#asynchronousxamarinwaithandle

Wait Handles and Xamarin Forms


I am currently working on a proof of concept application using the Xamarin free trial, and I have hit a rather interesting little problem... Here is the code I am using within a Portable Class Library:

using System;
using System.Net;
using Newtonsoft.Json;

namespace poc
{
    public class CurrentWeatherInformation
    {

        public string WeatherText { get; set; }

        public CurrentWeatherInformation (string cityName)
        {
            // api.openweathermap.org/data/2.5/weather?q=Leeds
            var request = (HttpWebRequest)WebRequest.Create(string.Format("http://api.openweathermap.org/data/2.5/weather?q={0}", cityName));
            request.ContentType = "application/json";
            request.Method = "GET";
            object state = request;

            var ar = request.BeginGetResponse (WeatherCallbackMethod, state);
            var waitHandle = ar.AsyncWaitHandle as System.Threading.ManualResetEvent;

            waitHandle.WaitOne();
        }

        public void WeatherCallbackMethod(IAsyncResult ar)
        {
            object state = ar.AsyncState;
            var request = state as HttpWebRequest;
            var response = request.EndGetResponse(ar);
            var data = new System.IO.StreamReader (response.GetResponseStream ()).ReadToEnd ();
            this.WeatherText = data;
        }

    }
}

Essentially, I just want to call against a webservice and get a response, but I note with Xamarin that I am unable to do this using the good old GetResponse() method, and have to use BeginGetResponse() and EndGetResponse() instead, with the old IAsyncResult pattern. Shizzle.

Anyway, my problem is that the code following my waiting on the waitHandle is executing BEFORE the code in the callback, and I don't see why. This is precisely what we have the wait handle for!

Can anyone spot what I am sure will prove to be a simple mistake by a simpleton?


Solution

  • On Windows Phone you are forced to use the async API. When you try to wait for a result of an async method synchronously on main thread you can end up in an infinite loop. Use async and await when you do expensive things. It's the common pattern for doing asynchronous work.

    Take a look at some tutorials:

    https://visualstudiomagazine.com/articles/2013/10/01/asynchronous-operations-with-xamarin.aspx

    http://developer.xamarin.com/recipes/android/web_services/consuming_services/call_a_rest_web_service/

    How to implement Android callbacks in C# using async/await with Xamarin or Dot42?

    https://github.com/conceptdev/xamarin-forms-samples/blob/master/HttpClient/HttpClientDemo/GeoNamesWebService.cs