2009-10-21 3 views
0

У меня есть страница, которая должна объединить данные из четырех разных веб-записей в один список элементов. В настоящее время я запускаю их последовательно, добавляя один список, а затем привязывая этот список к моему ретранслятору.несколько веб-запросов асинхронно в asp.net?

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

Как я могу выполнить четыре (это может даже увеличиться!) Одновременно, имея в виду, что каждый результат должен быть подан в один список?

большое спасибо!

EDIT: упрощенный пример того, что я делаю:

var itm1 = Serialize(GetItems(url1)); 
list.AddRange(itm1); 
var itm2 = Serialize(GetItems(url2)); 
list.AddRange(itm2); 

string GetItems(string url) 
{ 
    var webRequest = WebRequest.Create(url) as HttpWebRequest; 
    var response = webRequest.GetResponse() as HttpWebResponse; 

    string retval; 
    using (var sr = new StreamReader(response.GetResponseStream())) 
    { retval = sr.ReadToEnd(); } 
    return retval; 
} 
+0

У вас есть код, который вы можете опубликовать, чтобы показать нам, как вы в настоящее время загружаете эти запросы? –

+0

добавил упрощенный пример того, как я это делаю. Serialize() просто преобразует json-строку в класс, указанный для коллекции List. – SelAromDotNet

+0

Я думаю вместо того, чтобы запускать запрос асинхронно с BeginGetResponse, который, кажется, ничего мне не спасает, мне нужно запустить метод GetItems асинхронно, поэтому что 4 запроса могут выполняться одновременно. Я думал об использовании потоков до и теперь, когда я смотрю на свою проблему, похоже, что лучше всего сделать это каждый выпуск GetItems в отдельном потоке, но как его синхронизировать, чтобы приложение запускало их одновременно, затем агрегирует все их результаты? – SelAromDotNet

ответ

2

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

Что вы можете сделать, так это создать 4 делегата async, каждый из которых указывает на соответствующий веб-метод. Сделайте BeginInvoke на всех из них. И затем используйте WaitHandle, чтобы ждать всех. Нет необходимости использовать обратные вызовы, в вашем случае, поскольку вы не хотите продолжать работу, пока обрабатываются веб-методы, а скорее подождите, пока все веб-методы не закончат выполнение.

Только после того, как все веб-методы выполнены, будет выполняться код после выполнения команды wait. Здесь вы можете комбинировать 4 результата.

Вот пример кода, я разработал для вас:

class Program 
    { 
     delegate string DelegateCallWebMethod(string arg1, string arg2); 

     static void Main(string[] args) 
     { 
      // Create a delegate list to point to the 4 web methods 
      // If the web methods have different signatures you can put them in a common method and call web methods from within 
      // If that is not possible you can have an List of DelegateCallWebMethod 
      DelegateCallWebMethod del = new DelegateCallWebMethod(CallWebMethod); 

      // Create list of IAsyncResults and WaitHandles 
      List<IAsyncResult> results = new List<IAsyncResult>(); 
      List<WaitHandle> waitHandles = new List<WaitHandle>(); 

      // Call the web methods asynchronously and store the results and waithandles for future use 
      for (int counter = 0; counter < 4;) 
      { 
       IAsyncResult result = del.BeginInvoke("Method ", (++counter).ToString(), null, null); 
       results.Add(result); 
       waitHandles.Add(result.AsyncWaitHandle); 
      } 

      // Make sure that further processing is halted until all the web methods are executed 
      WaitHandle.WaitAll(waitHandles.ToArray()); 

      // Get the web response 
      string webResponse = String.Empty; 
      foreach (IAsyncResult result in results) 
      { 
       DelegateCallWebMethod invokedDel = (result as AsyncResult).AsyncDelegate as DelegateCallWebMethod; 
       webResponse += invokedDel.EndInvoke(result); 
      } 
     } 


     // Web method or a class method that sends web requests 
     public static string CallWebMethod(string arg1, string arg2) 
     { 
      // Code that calls the web method and returns the result 

      return arg1 + " " + arg2 + " called\n"; 
     } 

    } 
1

Как о запуске каждого запроса на своем собственном отдельном потоке, а затем добавляя результаты в списке?

+0

Я думаю, что создание потоков для выполнения такой операции абсолютно НЕТ-НЕТ, если у вас нет чего-то особенного ... как изменение приоритета потока (по умолчанию потоки имеют нормальный приоритет). –

1

@Josh: Что касается вашего вопроса об отправке 4 (потенциально более) асинхронных запросов и отслеживание ответов (например, кормить в списке) , Вы можете написать 4 запроса и 4 обработчика ответов, но поскольку у вас потенциально будет больше запросов, вы можете написать асинхронный цикл. Классическая для цикла состоит из init, условия и приращения. Вы можете разбить классический цикл на цикл while и по-прежнему быть эквивалентным. Затем вы делаете цикл while в рекурсивную функцию. Теперь вы можете сделать его асинхронным. Я поставил несколько примеров скриптов здесь на http://asynchronous.me/. В вашем случае выберите цикл for в параметрах. Если вы хотите, чтобы запросы отправлялись последовательно, то есть один запрос после предыдущего ответа (request1, response1, request2, response2, request3, response3 и т. Д.), Затем выберите последовательную связь (то есть последовательную), но код немного больше запутана. С другой стороны, если вам не нужен порядок, в котором получены ответы (случайный порядок), затем выберите «Параллельная связь» (то есть параллельно), код более интуитивно понятен. В любом случае каждый ответ будет связан с его соответствующим запросом идентификатором (простым целым числом), чтобы вы могли отслеживать их все. Сайт предоставит вам образец сценария. Образцы написаны на JavaScript, но они применимы к любому языку.Адаптируйте скрипт к языку и настройкам кодирования. С помощью этого сценария ваш браузер будет отправлять 4 запроса асинхронно, а по идентификатору вы сможете отслеживать, к какому запросу соответствует ответ. Надеюсь это поможет./Thibaud Lopez Schneider

Смежные вопросы