Приложение WP7 никогда не выходит из BeginGetResponse и переходит в функцию обратного вызова - PullRequest
6 голосов
/ 11 февраля 2011

У меня есть следующий код:

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 ]

8 голосов
/ 04 апреля 2011

Если вы создали запрос HttpWebRequest в потоке пользовательского интерфейса, убедитесь, что вы не блокируете поток пользовательского интерфейса, в противном случае вы можете заблокировать его.

Образец рабочего стола .NET, который вы связали, не являетсяоптимизирован для текущего стека телефонной сети.Вам следует изменить код, чтобы создать запрос HttpWebRequest в фоновом потоке.

3 голосов
/ 04 апреля 2011

Я не вижу, что не так с вашим кодом (может быть, поможет полный пример того, что вы пытаетесь сделать), но вот простой рабочий пример способа выполнения действия, которое вы хотите сделать. Он отправляет некоторые данные в URI, а затем передает ответ в функцию обратного вызова:

Просто выполните так (использование 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...