2011-02-11 20 views
6

Tôi có đoạn mã sau:ứng dụng WP7 không bao giờ thoát BeginGetResponse và đi vào hàm callback

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

Tuy nhiên khi mã của tôi chạm BeginGetResponse nó không bao giờ thoát ra (và tôi không đánh một breakpoint trong hàm GetResponseCallback). Tôi đã thử thêm lời gọi BeginInvoke, nhưng tôi vẫn chưa bao giờ nhập phương thức này. Mã này hoạt động trong ứng dụng giao diện điều khiển cửa sổ - trên Windows Phone 7 mà nó không có nghĩa là

Có ai có thể nhìn thấy những gì tôi đang làm không?

Cảm ơn.

+0

Tôi không thể nhìn thấy nơi bạn đang tạo HttpWebRequest –

Trả lời

8

Nếu bạn đã tạo HttpWebRequest trên chuỗi giao diện người dùng, hãy đảm bảo bạn không chặn luồng giao diện người dùng, nếu không bạn có thể bế tắc.

Mẫu từ máy tính để bàn .NET bạn đã liên kết không được tối ưu hóa cho ngăn xếp mạng điện thoại hiện tại. Bạn nên thay đổi mã để bạn tạo HttpWebRequest trên một chuỗi nền.

+0

Ngay cả khi cuộc gọi được thực hiện trong UI thread nó sẽ không khiến cuộc gọi không bao giờ trở lại. Phải không? –

+0

Chuỗi nền nội bộ mà thời gian chạy được tạo thay cho bạn khi bạn gửi yêu cầu gọi lại cho chuỗi đã tạo HWR. Nếu chuỗi đó bị chặn, yêu cầu web của bạn không thể tiếp tục. Đó là lý do tại sao chúng tôi đề xuất trên điện thoại để tạo HWR của bạn trên một chuỗi nền. Bằng cách này, họ sẽ không bao giờ ảnh hưởng đến chuỗi giao diện người dùng của bạn. –

3

Tôi không thể thấy mã của bạn có gì sai (có thể là ví dụ hoàn chỉnh về những gì bạn đang cố gắng làm) nhưng đây là ví dụ đơn giản về cách thực hiện hành động bạn muốn thực hiện.
Nó đăng tải một số dữ liệu vào một URI và sau đó vượt qua để phản ứng với một hàm callback:

Đơn giản chỉ cần thực hiện như thế này (sử dụng một BackgroundWorker là không cần thiết nhưng được khuyến khích)

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

Đây là chức năng gọi lại nó đề cập đến:
(bạn có thể thay đổi tuy nhiên điều này là phù hợp với nhu cầu của bạn.)

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

Dưới đây là phương pháp thực tế:

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

và đây là phần mở rộng/phương pháp helper nó sử dụng:

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; 
    } 
} 
Các vấn đề liên quan