【问题标题】:Execute multiple webrequests in WP7?在 WP7 中执行多个网络请求?
【发布时间】:2011-07-15 12:27:45
【问题描述】:

我有一个我想使用 httpWebRequest 访问的地址列表。 我只需要服务器返回的状态码。

我试图遍历它们并在它们中的每一个上开始一个 httpWebRequest,但是我只收到来自最后一个的回调。 似乎一次只允许一个网络请求。

我很难理解如何在没有 GetResponse 的情况下执行此操作,这在 silverlight 中是不允许的。

代码在后台工作程序中运行。 我正在使用 Mango - WP7.1

我该如何解决?

foreach (var current in Addresses)
        {
            var request = HttpWebRequest.Create(current);
            request.BeginGetResponse(r =>
            {
                try
                {
                    var response = (HttpWebResponse)request.EndGetResponse(r);
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        //BOOM RECEIVED
                    });
                }
                catch (Exception)
                {
                    Debug.WriteLine("Error in EndGetResponse");
                }
            }, null);
        }

提前致谢 =)

【问题讨论】:

  • 是的,我正在使用芒果 =)
  • 你收到什么样的“BOOM”?
  • 我收到状态码,然后更新模型。 BOOM 只是为了说明收到了一些东西 =)
  • 我想知道您是否可以在 Caliburn 微协同中进行这样的迭代,其中每个请求都会产生返回,处理返回,继续。

标签: windows-phone-7 httpwebrequest backgroundworker


【解决方案1】:

您的单一响应问题很可能是由您使用匿名方法以及将这些方法放入循环时的作用域工作方式引起的。在循环的每个步骤中,您都在丢弃之前的请求引用。

在此处查看我关于该主题的博文http://csainty.blogspot.com/2010/10/windows-phone-7asynchronous-programming.html

说明这一点的最简单方法是使用完整方法重写您的代码,这迫使您考虑范围,而不是仅仅在您的委托中盲目地引用外部变量。

foreach (var current in Addresses)
{
  var request = HttpWebRequest.Create(current);
  request.BeginGetResponse(EndGetResponse, new RequestState { Request = request, Address = current });
}


private void EndGetResponse(IAsyncResult result) {
  try {
    var state = (RequestState)result.AsyncState;
    var response = (HttpWebResponse)state.Request.EndGetResponse(result);
    Deployment.Current.Dispatcher.BeginInvoke(GotResponse, state.Address, response.StatusCode);
  } catch (Exception) {
    Debug.WriteLine("Error in EndGetResponse");
  }
}

private void GotResponse(Address address, HttpStatusCode code) {
  //BOOM RECEIVED
}

public class RequestState {
  HttpWebRequest Request { get; set; }
  Address Address { get; set; }
}

一旦您解决了范围界定问题,如果您愿意,您可以出于文体原因重写回匿名方法。

这只会解决您获取所有响应的第一个问题,但是,我假设您还需要在所有请求完成后运行一些代码来检查整个批次的状态?
这完全是一个不同的问题。

你不能使用 WaitOne() 或类似的东西,它会锁定你的线程并阻止请求实际运行。您可能希望在您的 BOOM 代码中调用另一个方法来存储结果并检查是否所有结果都在。

【讨论】:

  • 我知道使用完整方法而不是匿名方法将如何解决问题。但是,如果问题本身是匿名方法的使用,我以后如何将它重写为匿名方法?我很好奇,因为以匿名方式进行操作可以更轻松地引用循环中的对象。在我的项目中,地址位于一个对象上,而我正在迭代的集合实际上是这些对象的列表。当收到请求响应时,我需要启动请求的对象来保存一些返回值。
  • @Moulde 这就是问题所在,你不能只引用匿名方法之外的对象,我的博客文章解释了当你这样做时会发生什么。我已经更新了答案,以展示如何将多个状态传递给响应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-25
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
相关资源
最近更新 更多