2010-11-09 38 views
0

我有一個類去抓取一些數據並將其作爲字符串返回。當這個對象正在工作時,有一個讓用戶知道工作正在完成的旋轉圖標。問題是代碼在響應返回之前退出。我堅持一個替代此Http請求

while(response == null) 

在剛看到怎麼回事和

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

不點火。它在一個控制檯應用程序觸發好了,所以我把這個下來的東西,我這樣做,Silverlight不喜歡,繼承人的完整代碼:

public class HttpWorker 
{ 
    private HttpWebRequest request; 
    private HttpWebResponse response; 
    private string responseAsString; 
    private string url; 

    public HttpWorker() 
    { 

    } 

    public string ReadFromUrl(string Url) 
    { 
     url = Url; 
     request = (HttpWebRequest)WebRequest.Create(url); 

     request.CookieContainer = new CookieContainer(); 
     request.AllowAutoRedirect = true; 
     request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5.0.6"; 

     AsyncRequest(); // The Demon! 

     return responseAsString; 
    } 

    private void AsyncRequest() 
    { 
     request.BeginGetResponse(new AsyncCallback(FinaliseAsyncRequest), null); 
    } 

    private void FinaliseAsyncRequest(IAsyncResult AsyncResult) 
    { 
     response = (HttpWebResponse)request.EndGetResponse(AsyncResult); 


     if (response.StatusCode == HttpStatusCode.OK) 
     { 
      // Create the stream, encoder and reader. 
      Stream responseStream = response.GetResponseStream(); 
      Encoding streamEncoder = Encoding.UTF8; 
      StreamReader responseReader = new StreamReader(responseStream, streamEncoder); 
      responseAsString = responseReader.ReadToEnd(); 
     } 
     else 
     { 
      throw new Exception(String.Format("Response Not Valid {0}", response.StatusCode)); 
     } 
    } 

} 

回答

1

你在UI線程進入繁忙的環路與(while response == null)HttpRequest的異步回調將在UI線程中傳遞,因此如果您在同一線程上循環,回調將永遠不會運行。您需要返回以允許主消息循環運行,然後您的異步回調將被傳遞。

上面的設計表明,你真正想要的是同步獲取。忘記回撥,只需撥打電話FinaliseAsyncRequest內部ReadFromUrl自己。用戶界面將掛起,直到請求完成,但它聽起來像這就是你想要的。

+0

嗯掛也會停止任何「等待」圖形或我已經去。我想我需要重新設計。我只是不確定如何繼續使用數據。 – deanvmc 2010-11-09 17:36:11

+0

來自'HttpWebRequest'的回調不會在UI線程上執行。 'WebClient'觸發它在UI線程上的回調。 – 2010-11-09 19:57:11

+0

我對答案感到困惑,他如何從ReadFromUrl中調用FinaliseAsyncRequest?該請求不會被啓動,對吧?我試圖從發出請求的方法中返回一個值來完成同樣的事情。 – CACuzcatlan 2010-11-19 00:17:00

0

從Web服務器獲取字符串的最簡單方法是使用WebClient.DownloadStringAsync()MSDN docs)。

嘗試是這樣的:

private void DownloadString(string address) 
{ 
    WebClient client = new WebClient(); 
    Uri uri = new Uri(address); 

    client.DownloadStringCompleted += DownloadStringCallback; 
    client.DownloadStringAsync(uri); 

    StartWaitAnimation(); 
} 


private void DownloadStringCallback(object sender, DownloadStringCompletedEventArgs e) 
{ 
    // Do something with e.Result (which is the returned string) 

    StopWaitAnimation(); 
} 

注意回調UI線程上執行,所以你應該只使用此方法,如果您的回調方法沒有做非常多,因爲它會阻止,而它的UI執行。

如果您需要更多的網絡請求控制,那麼您可以使用HttpWebRequest。

如果你真的必須模仿同步行爲看看Faking synchronous calls in Silverlight WP7