2011-02-11 47 views
6

我有以下代碼:WP7應用從未退出BeginGetResponse並進入回調函數

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,它doesn'teorg

有人能看到我在做什麼錯?

謝謝。

+0

我不能看到你正在創建的HttpWebRequest – 2011-04-03 00:10:56

回答

8

如果您已經創建了HttpWebRequest的UI線程上,然後確保你不會阻塞UI線程,否則,你可以死鎖。

從.NET已經鏈接了當前手機網絡堆棧未優化桌面的樣品。您應該更改代碼,以便在後臺線程上創建HttpWebRequest。

+0

即使呼叫是在UI線程做它不會導致呼叫永遠不會返回。會嗎? – 2011-04-08 18:02:13

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