2011-02-11 8 views
6

Mam następujący kod:WP7 aplikacja nigdy nie wychodzi BeginGetResponse i przechodzi do funkcji zwrotnej

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"))); 
     } 

Jednak gdy mój kod uderza BeginGetResponse nigdy nie wyjdzie (i nie uderzy punkt przerwania w funkcji GetResponseCallback). Próbowałem dodać wywołanie BeginInvoke, ale wciąż nie wprowadzam tej metody. Ten kod działa w aplikacji konsoli systemu Windows - jest to na Windows Phone 7, że nie robi onn'teorg

Czy ktoś może zobaczyć, co robię źle?

Dzięki.

+0

nie widzę gdzie tworzysz HttpWebRequest –

Odpowiedz

8

Jeśli utworzyłeś HttpWebRequest w wątku UI, upewnij się, że nie blokujesz wątku interfejsu użytkownika, w przeciwnym razie możesz zakleszczać.

Próbka z podłączonego pulpitu .NET nie jest zoptymalizowana dla bieżącego stosu sieci telefonicznej. Powinieneś zmienić kod, aby utworzyć HttpWebRequest na wątku tła.

+0

Nawet jeśli połączenie zostało dokonane w interfejsie przewlecz nie ponieważ wywołanie nigdy nie powróci. Czy to prawda? –

+0

Wewnętrzny wątek tła, który środowisko wykonawcze utworzyło w Twoim imieniu podczas wysyłania żądania, oddzwania do wątku, który utworzył HWR. Jeśli ten wątek zostanie zablokowany, twoja prośba nie może być kontynuowana. Dlatego zalecamy, aby w telefonie utworzyć HWR na wątku w tle. W ten sposób nigdy nie wpłyną na twój wątek UI. –

3

Nie widzę, co jest nie tak z Twoim kodem (może być kompletny przykład tego, co próbujesz zrobić), ale oto prosty przykład działania, który chcesz wykonać.
To stanowisk jakieś dane do URI, a następnie przechodzi repsonse do funkcji callback:

Wystarczy wykonać tak (użycia BackgroundWorker nie jest konieczne, ale jest zalecane)

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

Oto funkcja zwrotna odnosi się do:
(można zmienić to jednak jest odpowiedni do swoich potrzeb.)

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); 
     } 
    }); 
} 

Oto rzeczywisty sposób:

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); 
    } 
} 

i tutaj są rozszerzeniem metody/pomocnika to wykorzystuje:

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; 
    } 
} 
Powiązane problemy