Последовательная обработка нескольких асинхронных HTTP-запросов в Silverlight - PullRequest
3 голосов
/ 05 февраля 2011

Из-за асинхронной природы доступа http через WebClient или HttpWebRequest в Silverlight 4, когда я хочу выполнять несколько запросов http get / posts, я нахожу, что пишу код, который выглядит следующим образом:

doFirstGet(someParams, () =>   
  {
    doSecondGet(someParams, () =>
      {
        doThirdGet(...
      }   
  });

Или что-то подобное. Я закончу вложением последующих вызовов в обратные вызовы, обычно реализуемые с использованием лямбда-выражений. Даже если я разбью вещи на действия или отдельные методы, это все равно будет трудно читать.

У кого-нибудь есть чистое решение для последовательного выполнения нескольких http-запросов в SL 4?

Мне не нужен код, который фактически запускает все это, чтобы быть синхронным, но мне нужно, чтобы запросы выполнялись последовательно, поэтому каждый запрос должен быть эффективно синхронным.

Ответы [ 3 ]

2 голосов
/ 08 февраля 2011

Взгляните на несколько моих постов в блоге по этому вопросу: -

Простой асинхронный оператор Runner - Часть 1
Простой асинхронный оператор Runner - Часть 2

Статьи немного глубоки, потому что они сосредоточены на фактической реализации, идея не должна включать в себя модные фреймворки, просто чтобы сделать это.Единственный код, который вам нужен, на самом деле есть в статьях, никаких дополнительных dll или zip-файлов для загрузки.

Однако обратите внимание на часть 2, способ представить, как будет выглядеть ваш код, если бы было возможно синхронное кодирование.В вашем случае ваш код будет выглядеть так: -

void StuffToDo()
{
    doFirstGet(someParams);
    doSecondGet(someParams);
    doThirdGet(...);
}

Следующим шагом является изменение содержимого методов "do", чтобы вместо него возвращалось AsyncOperation.В настоящее время они, вероятно, выглядят примерно так: -

void doFirst(someParams, Action callback)
{
    SomeAsyncObj thing = new SomeAsyncObj();
    thing.OnCompleted += (s, args) { callback() };
    thing.DoSomethingAsync();
} 

Вы должны преобразовать его в: -

AsyncOperation doFirst(someParams)
{
    return (completed) =>
    {
        SomeAsyncObj thing = new SomeAsyncObj();
        thing.OnCompleted += (s, args) =>
        {
            try
            {
                completed(null);
            }
            catch (Exception err)
            {
                completed(err);
            }
        };
        thing.DoSomethingAsync(source);
    };
}

Третий шаг - изменить ваш воображаемый синхронный код следующим образом: -

IEnumerable<AsyncOperation> StuffToDo()
{
    yield return doFirstGet(someParams);
    // Do some other synchronous stuff here, this code won't run until doFirstGet has completed.
    yield return doSecondGet(someParams);
    // Do some other synchronous stuff here, this code won't run until doSecondGethas completed.
    yield return doThirdGet(...);
    // Do some final synchronous stuff here, this code won't run until doThirdGethas completed.

}

Наконец, вызов StuffToDo меняется на: -

StuffToDo().Run((err) =>
{
   // report any error in err sensibly
});
1 голос
/ 08 февраля 2011
  1. Инкапсулировать каждый запрос в класс
  2. Создать коллекцию или массив запросов
  3. Выполнять итерацию в процессе сбора и обработки каждого запроса.
1 голос
/ 05 февраля 2011

Я столкнулся с этой проблемой. Я нашел сопрограммы очень полезными, я основывал свои идеи на работе Джереми Ликнесса и Роба Айзенберга.

Эта ссылка даст более подробную информацию.

...