Выполнить несколько веб-запросов в WP7?

У меня есть список адресов, которые я хочу посетить с помощью 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);
        }

Заранее спасибо =)


person Moulde    schedule 15.07.2011    source источник
comment
Да, я использую манго =)   -  person Moulde    schedule 15.07.2011
comment
Какой БУМ вы получаете?   -  person CodeZombie    schedule 15.07.2011
comment
Я получаю код состояния, а затем обновляю модель. БУМ был просто для иллюстрации того, что что-то было получено =)   -  person Moulde    schedule 15.07.2011
comment
Интересно, можно ли было бы повторить такую ​​же итерацию в микро-сопрограммировании Caliburn, где каждый запрос возвращал бы результат, возвращал обработку, продолжал бы работать.   -  person Derek Beattie    schedule 16.07.2011


Ответы (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, который сохраняет результат и проверяет, все ли результаты уже получены.

person Chris Sainty    schedule 15.07.2011
comment
Я вижу, как использование полных методов вместо анонимных решит проблему. Но как я смогу потом переписать его на анонимные методы, если сама проблема заключается в использовании анонимных методов? Мне любопытно, потому что анонимный способ упрощает обращение к объектам в цикле. В моем проекте адрес расположен на объекте, а коллекция, которую я повторяю, на самом деле представляет собой список этих объектов. И когда ответ на запрос получен, мне нужен объект, который запустил запрос, чтобы сохранить некоторые из возвращаемых значений. - person Moulde; 15.07.2011
comment
@Moulde В этом проблема, вы не можете просто ссылаться на объекты вне анонимного метода, в моем сообщении в блоге объясняется, что происходит, когда вы это делаете. Я обновил ответ, чтобы показать, как вы можете передать в ответ более одной части состояния. - person Chris Sainty; 16.07.2011