(C#)异步HTTPWebRequest无法联系服务器

时间:2010-12-09 00:37:33

标签: c# httpwebrequest

我正在尝试开发Windows Phone 7应用程序。此应用程序的一部分包括联系API以检索某些数据。为此,我正在使用HTTPWebRequest和我编写的一个小助手类;我调用HTTPHelper的sendAPIRequest,然后检索结果。

问题在于异步请求启动后的执行链。通过我的调试,我发现调用了BeginGetRequestStream的回调requestCallBack。此回调随后调用BeginGetResponse及其回调;不幸的是,它的回调(responseCallBack)永远不会触发。我已经确定永远不会联系API所在的服务器(Apache的日志中没有任何内容),并且在执行request.BeginGetResponse之后,调试器会显示一个空的本地列表和一个空堆栈;永远不会触发回调,程序无处可去。我已经尝试过所有可以想到的调试类型,但我现在已经结束了。没有异常被抛出,没有任何东西看起来 - 程序只是无法联系服务器并继续。

这是我正在使用的代码: 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);
    }

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); } 关于这里做错了什么的任何建议?

感谢您提出的所有建议。

1 个答案:

答案 0 :(得分:2)

尝试拔出readyToGo.WaitOne()。这将导致线程停止并等待信号。请求可能需要在该线程上进行处理,因此不会被调用。

奇怪的是,几分钟前我遇到了与重置事件非常类似的问题,尽管它是使用WPF而不是HttpRequests :)。

顺便说一句,我在CodePlex上有一个代码参考库,其中包含一个HttpWebRequest帮助程序(它可能不会直接帮助你,只是想我会提到它)。你可以随意使用它(甚至只是为了获取你喜欢的部分代码)。该项目名为BizArk,该类称为WebHelper。