2010-11-09 40 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