WP7应用程序永远不会退出BeginGetResponse并进入回调函数

时间:2011-02-11 01:12:02

标签: c# windows-phone-7

我有以下代码:

private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            // End the operation
            Stream postStream = request.EndGetRequestStream(asynchronousResult);

            //Console.WriteLine("Please enter the input data to be posted:");
            //string postData = Console.ReadLine();
            string postData = "my data";

            // Convert the string into a byte array.
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Write to the request stream.
            postStream.Write(byteArray, 0, postData.Length);
            postStream.Close();

                // Start the asynchronous operation to get the response
                IAsyncResult result =
                      (IAsyncResult)request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);

        }

        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            // End the operation
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
            Stream streamResponse = response.GetResponseStream();
            StreamReader streamRead = new StreamReader(streamResponse);
            string responseString = streamRead.ReadToEnd();
            Console.WriteLine(responseString);
            // Close the stream object
            streamResponse.Close();
            streamRead.Close();

            // Release the HttpWebResponse
            response.Close();
            allDone.Set();

            Dispatcher.BeginInvoke((Action)(() => Debug.WriteLine("George")));
        }

然而,当我的代码命中BeginGetResponse时,它永远不会退出(我在GetResponseCallback函数中没有遇到断点)。我尝试添加BeginInvoke调用,但我仍然没有输入此方法。此代码适用于Windows控制台应用程序 - 它位于Windows Phone 7上,它不会使用

谁能看到我做错了什么?

感谢。

2 个答案:

答案 0 :(得分:8)

如果您已在UI线程上创建了HttpWebRequest,请确保不阻止UI线程,否则可能会死锁。

您链接的桌面.NET中的示例未针对当前的手机网络堆栈进行优化。您应该更改代码,以便在后台线程上创建HttpWebRequest。

答案 1 :(得分:3)

我看不出你的代码有什么问题(也许你正在尝试做的事情的完整例子可能会有所帮助),但这是一个简单的工作示例,说明了你想要做的动作。
它将一些数据发布到URI,然后将repsonse传递给回调函数:

只需像这样执行(不需要使用BackgroundWorker,但建议使用)

var bw = new BackgroundWorker();
bw.DoWork += (o, args) => PostDataToWebService("http://example.com/something", "key=value&key2=value2", MyCallback);
bw.RunWorkerAsync();

以下是它所引用的回调函数:
(你可以根据自己的需要改变它。)

public static void MyCallback(string aString, Exception e)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        if (e == null)
        {
            // aString is the response from the web server
            MessageBox.Show(aString, "success", MessageBoxButton.OK);
        }
        else
        {
            MessageBox.Show(e.Message, "error", MessageBoxButton.OK);
        }
    });
}

这是实际的方法:

public void PostDataToWebService(string url, string data, Action<string, Exception> callback)
{
    if (callback == null)
    {
        throw new Exception("callback may not be null");
    }

    try
    {
        var uri = new Uri(url, UriKind.Absolute);
        var req = HttpWebRequest.CreateHttp(uri);

        req.ContentType = "application/x-www-form-urlencoded";
        req.Method = "POST";

        AsyncCallback GetTheResponse = ar =>
            {
                try
                {
                    var result = ar.GetResponseAsString();

                    callback(result, null);
                }
                catch (Exception ex)
                {
                    callback(null, ex);
                }
            };

        AsyncCallback SetTheBodyOfTheRequest = ar =>
            {
                var request = ar.SetRequestBody(data);

                request.BeginGetResponse(GetTheResponse, request);
            };

        req.BeginGetRequestStream(SetTheBodyOfTheRequest, req);
    }
    catch (Exception ex)
    {
        callback(null, ex);
    }
}

以下是它使用的扩展/帮助方法:

public static class IAsyncResultExtensions
{
    public static string GetResponseAsString(this IAsyncResult asyncResult)
    {
        string responseString;

        var request = (HttpWebRequest)asyncResult.AsyncState;

        using (var resp = (HttpWebResponse)request.EndGetResponse(asyncResult))
        {
            using (var streamResponse = resp.GetResponseStream())
            {
                using (var streamRead = new StreamReader(streamResponse))
                {
                    responseString = streamRead.ReadToEnd();
                }
            }
        }

        return responseString;
    }

    public static HttpWebRequest SetRequestBody(this IAsyncResult asyncResult, string body)
    {
        var request = (HttpWebRequest)asyncResult.AsyncState;

        using (var postStream = request.EndGetRequestStream(asyncResult))
        {
            using (var memStream = new MemoryStream())
            {
                var content = body;

                var bytes = System.Text.Encoding.UTF8.GetBytes(content);

                memStream.Write(bytes, 0, bytes.Length);

                memStream.Position = 0;
                var tempBuffer = new byte[memStream.Length];
                memStream.Read(tempBuffer, 0, tempBuffer.Length);

                postStream.Write(tempBuffer, 0, tempBuffer.Length);
            }
        }

        return request;
    }
}