3

我再次遇到PCL(可移植類庫)中的WebRequest問題。WP8上的HttpWebRequest.BeginGetResponse

我有這樣一段代碼:

static ManualResetEvent allDone = new ManualResetEvent(false); 
    static string doc; 

    static public void AddAnime(string encodedLogin, string id, int episodes, int status, int score) 
    { 
     if (string.IsNullOrEmpty(encodedLogin)) 
     { 
      throw new ArgumentException(); 
     } 
     else 
     { 
      doc = String.Format("anime_id={0}&status={1}&episodes={2}&score={3}", id, "watching", episodes, score); 

      HttpWebRequest request = HttpWebRequest.CreateHttp("http://mal-api.com/animelist/anime"); 

      request.Method = "POST"; 
      request.Headers["Authorization"] = encodedLogin; 

      request.BeginGetRequestStream(new AsyncCallback(GetRequestCallBack), request); 

      allDone.WaitOne(); 

      s.ToString(); 
     } 
    } 

    static private void GetRequestCallBack(IAsyncResult aResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)aResult.AsyncState; 

     Stream postStream = request.EndGetRequestStream(aResult); 

     byte[] byteArray = Encoding.UTF8.GetBytes(doc); 

     postStream.Write(byteArray, 0, doc.Length); 
     postStream.Flush(); 

     request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request); 
    } 

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

     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult); 

     Stream dataStream = response.GetResponseStream(); 
     StreamReader streamReader = new StreamReader(dataStream); 

     string responseString = streamReader.ReadToEnd(); 

     //Do something with string here 

     allDone.Set(); 
    } 

現在的問題是,當我在一個樣本控制檯應用程序調用AddAnime,這種運行完全正常,但是當我把它從我的WP8設備或模擬器(WXGA),它卡在BeginGetResponse。它根本不會輸入GetResponseCallback(用斷點測試),並且在BeginGetResponse之後也不會繼續使用任何代碼。我已經等了兩分多鐘,這應該會產生一個TimeOutException(我認爲),但即便如此,一切都沒有發生。

  • 控制檯應用程序(的作品)
  • WP8 WXGA模擬器(不工作)
  • WP8設備連接(不工作)
  • WP8設備斷開連接(:

    我與測試不 工作)

對於我的PCL我的目標:

  • SL4和更高
  • WP7和更高
  • Windows應用商店
  • .NET 4.5

我怎麼能解決這個問題?不是用來保證交叉兼容性的PCL嗎?

+1

SideNote:爲什麼不使用TPL(async/await),如request.GetResponseAsync()?您的代碼可能更簡單並且易於維護。 –

+0

TPL花了一點時間去適應,但它是真棒 –

+0

我很喜歡,但我該如何使用目標SL4,WP7.1,WP8和Windows應用商店的便攜式類庫? –

回答

2

Windows Phone(和我認爲的Silverlight)顯式地阻止您等待UI線程上網絡操作的結果。您需要將線程的控制權返回給調用者 - 如果您嘗試阻止它,則會導致死鎖。

最簡單的方法是使用任務和異步/等待。我們發佈了一個Async Targeting Pack,它將此支持添加到您定位的平臺(以及針對它們的可移植類庫)。請注意,Windows Phone 7.0不受支持,您需要選擇Windows Phone 7.1/7.5(這是同樣的事情,但不同的地方使用不同的版本號)。