Search code examples
c#httpwebrequest

(C#) Asynchronous HTTPWebRequest Failing To Contact Server


I'm trying to develop a Windows Phone 7 application. Part of this application includes contacting an API to retrieve some data. To do so, I am utilizing HTTPWebRequest and a small helper class I've written; I call HTTPHelper's sendAPIRequest and then retrieve the result.

The problem lies in the chain of execution following the initiation of the asynchronous request. Through my debugging, I've discovered that BeginGetRequestStream's callback requestCallBack is called. This callback subsequently calls BeginGetResponse and its callback; unfortunately, its callback (responseCallBack) is never trigger. I've determined that the server the API is on is never contacted (there is nothing in Apache's logs), and after execution of request.BeginGetResponse, the debugger shows an empty list of locals and an empty stack; the callback is never triggered, and the program goes nowhere. I've tried all types of debugging I can think of, but am at an end here. No exceptions are thrown, nothing looks off--the program just simply fails to contact the server and continue.

Here's the code I'm using: public class HTTPHelper { public string postString { get; set; } public string responseData { get; set; }

    private static ManualResetEvent readyToGo = new ManualResetEvent(false);

    public void sendAPIRequest(string mode, string data)
    {
        GenericAPIRequest requestInformation = new GenericAPIRequest { data = data, device_id = getDeviceId(), method = mode };

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://192.168.1.69/api/master.php?source=client");
        request.ContentType = "application/x-www-form-urlencoded";
        request.Method = "POST";

        string postData = "device_id=" + getDeviceId() + "&data=" + JsonConvert.SerializeObject(requestInformation) + "&mode=" + mode;
        postString = postData;

        request.BeginGetRequestStream(new AsyncCallback(requestCallBack), request);

        // Stop the thread until we've finished our HTTP request
        readyToGo.WaitOne();
        return;
    }
    private void requestCallBack(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

        Stream postStream = request.EndGetRequestStream(asynchronousResult);

        byte[] postBytes = Encoding.UTF8.GetBytes(postString);

        postStream.Write(postBytes, 0, postString.Length);
        postStream.Close();

        request.BeginGetResponse(new AsyncCallback(responseCallBack), request);
        return;
    }
    private void responseCallBack(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
        Stream streamResponse = response.GetResponseStream();
        StreamReader streamRead = new StreamReader(streamResponse);

        responseData = streamRead.ReadToEnd();

        streamResponse.Close();
        streamRead.Close();
        response.Close();

        // Release the thread...
        readyToGo.Set();
        return;

    }
    private string getDeviceId()
    {
        // Gets the unique device ID, allows us to track the device.
        byte[] result = null;
        object uniqueId;

        if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
            result = (byte[])uniqueId;

        return System.BitConverter.ToString(result);
    }

Any suggestions as to what's done wrong here?

Thanks for any and all suggestions you may have.


Solution

  • Try pulling out the readyToGo.WaitOne(). That will cause the thread to stop and wait for the signal. It's likely that the request needs to process on that thread and so is not getting called.

    Oddly I had a very similar problem with reset events just a few minutes ago, though it was with WPF instead of HttpRequests :).

    BTW, I have a code reference library on CodePlex that includes an HttpWebRequest helper (it probably won't directly help you here, just thought I would mention it). You are free to use it anyway you want (even just to take the parts of the code you like). The project is called BizArk and the class is called WebHelper.